Skip to content

design flaw: 'type' type cannot be used with address-of operator #588

Closed
@andrewrk

Description

@andrewrk

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:

  • ^x would be a pointer to type x.
  • &x would be taking the address of x.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions