remix logo

Hacker Remix

Zig's dot star syntax (value.*)

99 points by todsacerdoti 2 days ago | 93 comments

karmakaze 13 hours ago

This is a weird (to me) way of presenting Zig syntax and operation. I would generally assume that someone coming to Zig would be familiar with C/C++ or Rust and only need to be able to map Zig syntax to things they already know.

If the author's content is all in this 'assume no C background' style, it will be useful to those without previous manual memory management background in contrast to most articles that assume a lot of context.

klodolph 16 hours ago

This is the way that Pascal does it, which was always more sensible than prefix notation. Pascal uses ^

skissane 13 hours ago

In C you can use `[0]` as a postfix dereferencing operation... ugly but it works. I use it a lot in GDB. But I agree that Pascal does it better here, the dereferencing operator should have been postfix all along.

The thing I really wish C had, and which there is no straightforward workaround for, is postfix casting. When you do `((struct foo*)(COMPLEX_EXPRESSION))->field`, I think it would read a lot better if the `(struct foo*)` cast was on the same side as `->field`. Maybe something like `(COMPLEX_EXPRESSION)@(struct foo*)->field`

lostdog 12 hours ago

That is very nice. If you treat the star as a postfix operator, then even "->" is no longer needed:

   some_pointer*.field

skissane 11 hours ago

`->` shouldn't be necessary to begin with... if the LHS is a pointer already, `.` could just auto-dereference it instead of generating an error like it does now.

spacechild1 4 hours ago

Note that when you define smart pointer types C++ there is indeed a difference between `.` and `*` resp. `->`: the latter are typically overloaded to operate on the underlying pointer type whereas the former operates on the smart pointer class itself (e.g. calling `reset` on a `std::unique_ptr`). Not sure how you would do that with a single dereference operator.

fc417fc802 10 hours ago

I always wondered about that. Is there some technical reason that it was designed the way it was? Is it disambiguating something?

It seems like `.` could in theory be made to recursively dereference any number of layers down to the base type. It's not as though `.` has any other possible meaning when used directly against an address ... right?

skissane 10 hours ago

Historical reasons: early C compilers didn't actually keep track of what the type of the LHS was, so they needed `.` vs `->` to properly disambiguate. Later C compilers did start tracking that, so the difference in syntax was no longer necessary, but stuck for reasons of history and backward compatibility

https://retrocomputing.stackexchange.com/questions/10812/why...

pjmlp 7 hours ago

In a way, Zig is Modula-2 with curly brackets for folks with C background.

Yes, I know, comptime and such.

int_19h 4 hours ago

In Pascal, it's a distinct operator from field access, though.

What this actually reminds me of is Ada, where you write `value.all` to basically the same effect as Zig's `value.*`. It's as if everything is a struct with itself as a member.

loxodrome 17 hours ago

Nice explanation of zig's dereferencing operator. Thanks!

xg15 5 hours ago

Didn't know anything about Zig, but the .* syntax alone was straight-forward and easy to understand, as is regular copying from one existing memory location to another.

I think what seems weird though is more the "... = .{...}" syntax.

This makes it look as if there was some kind of anonymous object ".{...}" in memory that you're copying from, but there isn't. It's actually just a writing operation and the .{...} itself doesn't represent anything.

Maybe that was also what the author found confusing?