size_t a = a.sizeof; // This works
void main(){
size_t y = y.sizeof; // this fails
}
In y
’s initializer, y
hasn’t yet been inserted into the scope. This prevents bugs like
int a = a;
but prevents patterns like:
int* x = malloc((*x).sizeof);
although you can still do:
int* x; x = malloc((*x).sizeof);
More concerningly, you get unintended references to globals if you happen to reuse the name:
char y;
void main(){
size_t y = y.sizeof;
assert(y == y.sizeof); // fails, y == 1
}
You can also get weird code if your variable has the same name as a type:
struct foo {
}
void main(){
auto foo = foo();
auto foo2 = foo(); // Error: struct `foo` does not overload ()
}
In my opinion, it should be fine to refer to static properties or methods and so
void main(){
size_t y = y.sizeof;
}
should work, but because of how this was implemented it does slightly change the semantics if you happen to shadow a global.
Should this be fixed? or is this the intended design of the language?