3 ms·
To be honest your snippet isn't really C anymore by using a compiler builtin. I'm also annoyed by things like `foo(int N, const char x[N])` which compilation va
by Cloudef 1y ago
To be honest your snippet isn't really C anymore by using a compiler builtin. I'm also annoyed by things like `foo(int N, const char x[N])` which compilation vary wildly between compilers (most ignore them, gcc will actually try to check if the invariants if they are compile time known)
> I haven't really understood the advantage compared to simply running a program at build time.
Since both comptime and runtime code can be mixed, this gives you a lot of safety and control. The comptime in zig emulates the target architecture, this makes things like cross-compilation simply work. For program that generates code, you have to run that generator on the system that's compiling and the generator program itself has to be aware the target it's generating code for.
- uecker 1y agoIt also works with memcpy from the library: https://godbolt.org/z/Mc6M9dK4M https://godbolt.org/z/Mc6M9dK4M I just didn't feel like burdening godbolt with an inlclude. I do not understand your criticism of [N]. This gives compiler more information and catches errors. This is a good thing! Who could be annoyed by this: https://godbolt.org/z/EeadKhrE8 https://godbolt.org/z/EeadKhrE8 (of course, nowadays you could also define a descent span type in C) The cross-compilation argument has some merit, but not enough to warrant the additional complexity IMHO. Compile-time computation will also have annoying limitations and makes programs more difficult to understand. I feel sorry for everybody who needs to maintain complex compile time code generation. Zig certainly does it better than C++ but still..
- Cloudef 1y ago> I do not understand your criticism of [N]. This gives compiler more information and catches errors. This is a good thing! It only does sane thing in GCC, in other compilers it does nothing and since it's very underspec'd it's rarely used in any C projects. It's shame Dennis's fat pointers / slices proposal was not accepted. > warrant the additional complexity IMHO In zig case the comptime reduces complexity, because it is simply zig. It's used to implement generics, you can call zig code compile time, create and return types. This old talk from andrew really hammers in how zig is evolution of C: https://www.youtube.com/watch?v=Gv2I7qTux7g https://www.youtube.com/watch?v=Gv2I7qTux7g
- uecker 1y agoThen the right thing would be to complain about those other compilers. I agree that Dennis' fat pointer proposal was good. Also in Zig it does not reduce complexity but adds to it by creating an distinction between compile time and run-time. It is only lower complexity by comparing to other implementations of generic which are even worse.
- Cloudef 1y agoSure there's tradeoffs for everything, but if I had to choose between macros, templates, or zig's comptime, I'd take the comptime any time.
- uecker 1y agoTo each their own, I guess. I still find C to be so much cleaner than all the languages that attempt to replace it, I can not possibly see any of them as a future language for me. And it turns out that it is possible to fix issues in C if one is patient enough. Nowadays I would write this with a span type: https://godbolt.org/z/nvqf6eoK7 https://godbolt.org/z/nvqf6eoK7 which is safe and gives good code. update: clang is even a bit nicer https://godbolt.org/z/b99s1rMzh https://godbolt.org/z/b99s1rMzh although both compile it to a constant if the other argument is known at compile time. In light of this, the Zig solution does not impress me much: https://godbolt.org/z/1dacacfzc https://godbolt.org/z/1dacacfzc
- pjmlp 1y agoNot only it was a good proposal, since 1990 that WG14 has not done anything else into that sense, and doesn't look like it ever will.
- uecker 1y agoLet's see. We have a relatively concrete plan to add dependent structure types to C2Y: struct foo { size_t n; char (buf)[.n]; }; Once we have this, the wide pointer could just be introduced as syntactic sugar for this. char (buf)[:] = .. Personally, I would want the dependent structure type first as it is more powerful and low-level with no need to decide on a new ABI.
- quibono 1y agoPossibly a stupid question... what's a descent span type?
- uecker 1y agoSomething like this: https://godbolt.org/z/er9n6ToGP https://godbolt.org/z/er9n6ToGP It encapsulates a pointer to an array and a length. It is not perfect because of some language limitation (which I hope we can remove), but also not to bad. One limitation is that you need to pass it a typedef name instead of any type, i.e. you may need a typedef first. But this is not terrible.
- quibono 1y agoThanks, this is great! I've been having a look at your noplate repo, I really like what you're doing there (though I need a minute trying to figure out the more arcane macros!)
- uecker 1y agoIn this case, the generic span type is just #define span(T) struct CONCAT(span_, T) { ssize_t N; T* data; } And the array to span macro would just create such an object form an array by storing the length of the array and the address of the first element. #define array2span(T, x) ({ auto __y = &(x); (span(T)){ array_lengthof(__y), &(__y)[0] }; })