Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrewrk opened this issue Nov 6, 2017 · 3 comments
Closed

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

andrewrk opened this issue Nov 6, 2017 · 3 comments
Labels
bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Nov 6, 2017

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.

@andrewrk andrewrk added the bug Observed behavior contradicts documented or intended behavior label Nov 6, 2017
@andrewrk andrewrk added this to the 0.2.0 milestone Nov 6, 2017
@scurest
Copy link
Contributor

scurest commented Nov 6, 2017

C++ has a function std::addressof which always takes the address of its arguments for roughly this reason (namely the meaning of prefix & can vary, though because of operator overloading in that case). We could do something similar. & could stay the same, but you could add an @addressOf builtin to mean "I want the address of this, even if it's a type". The for-loop would then use @addressOf in its desugaring.

I admit it's a little... unzenful. But it'd be low-impact for something that's probably rare. I don't know. What do you think?

(btw, besides the syntax, Zig is okay with pointers and slices of types?)

@andrewrk
Copy link
Member Author

andrewrk commented Nov 6, 2017

(btw, besides the syntax, Zig is okay with pointers and slices of types?)

Yes, at compile time.

@andrewrk andrewrk modified the milestones: 0.2.0, 0.3.0 Mar 7, 2018
@phase
Copy link
Contributor

phase commented Apr 24, 2018

b is a pointer to i32 instead of &type

What is &type in this context? If it is not a pointer to a type, why not change that character to something else and leave the pointer character the same? Using & as an operator to get the address of something and as a type prefix for an address of a type is uniform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants