It also works with memcpy from the library: 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 (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..
> 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.
Then 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.
C also creates a distinction between compile-time and run-time, which is more arcane and complicated than that of Zig's, and your code uses it, too: macros (and other pre-processor programming). And there are other distinctions that are more subtle, such as whether the source of a target function is available to the caller's compilation unit or not, static or not etc..
C only seems cleaner and simpler if you already know it well.
My point is not about whether compile-time programming is simpler in C or in Zig, but that is in most cases the wrong solution. My example is also not about compile time programming (and does not use macro: https://godbolt.org/z/Mc6M9dK4M), but about letting the optimizer do its job. The end result is then leaner than attempting to write a complicated compile time solution - I would argue.
I don't know, to me it seems the blog tries to make the case that comptime is useful for low-level optimization: "Is this not amazing? We just used comptime to make a function which compares a string against "Hello!\n", and the assembly will run much faster than the naive comparison function. It's unfortunately still not perfect." But it turns out that a C compiler will give you the "perfect" code directly while the comptime Zig version is fairly complicated. You can argue that this was just a bad example and that there are other examples where comptime makes more sense. The thing is, about two decades ago I was similarly excited about expression-template libraries for very similar reasons. So I can fully understand how the idea of "seamlessly weaves comptime and runtime together" can appear cool. I just realized at some point that it isn't actually all that useful.
> But it turns out that a C compiler will give you the "perfect" code directly while the comptime Zig version is fairly complicated.
In this case both would (or could) give the "perfect" code without any explicit comptime programming.
> I just realized at some point that it isn't actually all that useful.
Except, again, C code often uses macros, which is a more cumbersome mechanism than comptime (and possibly less powerful; see, e.g. how Zig implements printf).
I agree that comptime isn't necessarily very useful for micro optimisation, but that's not what it's for. Being able to shift computations in time is usedful for more "algorithmic" macro optimisations, e.g. parsing things at compile time or generating de/serialization code.
Of course, a compiler could possibly also optimize the Zig code perfectly. The point is that the blogger did not understand it and instead created an overly complex solution which is not actually needed. Most C code I write or review does not use a lot of macros, and where they are used it seems perfectly fine to me.
To 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 which is safe and gives good code.
Something like this: 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.
Thanks, 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!)
In 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] }; })
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 (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..