-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
Consider this code:
const assert = @import("std").debug.assert;
comptime {
var a: i32 = 1;
const b = &a;
@compileLog(@typeOf(b));
*b = 2;
assert(a == 2);
}This works fine. The value printed from the @compileLog statement is &i32. This makes sense because b is a pointer to a.
Now let's do it with a type:
const assert = @import("std").debug.assert;
comptime {
var a: type = i32;
const b = &a;
@compileLog(b);
*b = f32;
assert(a == f32);
}$ ./zig build-obj test.zig
| &i32
/home/andy/dev/zig/build/test.zig:6:5: error: found compile log statement
@compileLog(b);
^
/home/andy/dev/zig/build/test.zig:7:5: error: attempt to dereference non-pointer type 'type'
*b = f32;
^
It doesn't work, because the & operator works differently for type than other types. Here, b is a pointer to i32 instead of &type which is how we wanted to use it.
This prevents other things from working too; for example if you had a []type{i32, u8, f64} and you tried to use a for loop, it crashes the compiler because internally a for loop uses the & operator on the array element.
This is a design flaw in zig; we can't have it both ways.
The only reasonable way I can think of to fix this so far is to introduce a new operator, so we don't have this double-purposed &. For example:
^xwould be a pointer to typex.&xwould be taking the address ofx.
I'm inclined to leave & as the address-of operator because that is the same as C. Using & as the pointer-to- operator is already different than C, so it's less cost to people learning the language to change it.