v icon indicating copy to clipboard operation
v copied to clipboard

Modifying an immutable pointer indirectly is allowed

Open jdonnerstag opened this issue 4 years ago • 9 comments

V version: V 0.2.4 c957f59.66a67de OS: windows, Microsoft Windows 10 Enterprise v19042 64-bit

What did you do?

struct AnotherStruct {
mut:
	str string
}

@[params]
pub struct MyOptions {
	data &AnotherStruct
}

pub fn fn_test(args MyOptions) {
	assert args.data.str == 'test'
	// args.str = "new"   // Compiler error. args.str is immutable
	mut x := args.data // should error
	x.str = 'why is this possible?'
	assert x.str == 'why is this possible?'
	assert args.data.str == 'why is this possible?'
}

fn main() {
	fn_test(
		data: &AnotherStruct{
			str: 'test'
		}
	)
}

What did you expect to see? A compiler error

What did you see instead? The test successfully compiling and executing

jdonnerstag avatar Dec 19 '21 14:12 jdonnerstag

Why shouldn't this be allowed? You're just copying a string into the mutable variable x.

Wertzui123 avatar Dec 19 '21 14:12 Wertzui123

May be I oversimplified it. The example below is bit closer to my real code.

I'm passing a immutable struct to a function. One of the immutable arguments is a pointer. Then I assign the immutable pointer to new mutable variable. And now I'm able to modify what meant to be immutable.

struct AnotherStruct {
mut:
	str string
}

[params]
pub struct MyOptions {
	data &AnotherStruct
}

pub fn fn_test(args MyOptions) {
	assert args.data.str == "test"
	// args.str = "new"   // Compiler error. args.str is immutable
	mut x := args.data // should error
	x.str = "why is this possible?"
	assert x.str == "why is this possible?"
	assert args.data.str == "why is this possible?"
}

fn test_1() {
	fn_test(data: &AnotherStruct{ str: "test" })
}

jdonnerstag avatar Dec 19 '21 15:12 jdonnerstag

I'm not an expert, but at:

// args.str = "new"   // Compiler error. args.str is immutable

The error is because the function argument is immutable, not because the structure field is immutable. Anyway, "args.str" doesn't exist.

Then

mut x := args.data

Is a pointer, so why it could not be possible to modify it?

It's a funny situation. I don't know what should be the behavior of V in this case.

Tanguy-SALMON avatar Jan 08 '22 05:01 Tanguy-SALMON

Is a pointer, so why it could not be possible to modify it?

Isn't such modification allowed only in unsafe{ } blocks? IDK, didn't try.

dumblob avatar Jan 08 '22 14:01 dumblob

This is a bug, good find.

Modifying an immutable pointer indirectly shouldn't be allowed.

medvednikov avatar Jan 08 '22 14:01 medvednikov

x is a pointer, so why it could not be possible to modify it?

It modifies what the pointer points to, which should be immutable.

BTW I edited the example to add highlighting and add a comment: mut x := args.data // should error

ntrel avatar Mar 23 '22 10:03 ntrel

This must have been discussed many times before somewhere, but I couldn't find any good references.

So @ntrel should that particular line really be an error? V string is immutable and thus guarantees copy semantics, right? So maybe that should do a full copy without any error?

I mean, any pointer shuffling or shallow copying etc. is just an optimization under the hood and shouldn't proliferate into the syntax/surface_language unless in unsafe{ }.

Or am I missing something?

dumblob avatar Mar 23 '22 14:03 dumblob

So @ntrel should that particular line really be an error? V string is immutable and thus guarantees copy semantics, right?

args.data is of type &AnotherStruct, not string. It's immutable so it's string field cannot be allowed to change.

ntrel avatar Mar 23 '22 14:03 ntrel

Oh, my bad - sorry for the fuss. Yes, that all makes sense. Maybe it originates from the special treatment due to [params]?

dumblob avatar Mar 24 '22 23:03 dumblob