Modifying an immutable pointer indirectly is allowed
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
Why shouldn't this be allowed?
You're just copying a string into the mutable variable x.
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" })
}
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.
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.
This is a bug, good find.
Modifying an immutable pointer indirectly shouldn't be allowed.
xis 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
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?
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.
Oh, my bad - sorry for the fuss. Yes, that all makes sense. Maybe it originates from the special treatment due to [params]?