5 ms·
Side topic: Didn't we have a is_const_eval equivalent in C? I seem to remember a dark magic macro doing precisely that on the lkml somewhere, but can't find it.
by Ne02ptzero 4y ago
Side topic: Didn't we have a is_const_eval equivalent in C? I seem to remember a dark magic macro doing precisely that on the lkml somewhere, but can't find it.
- einpoklum 4y agoThere is no compilation-time evaluation of functions and statements in C. You have constants, which can be expressions, but that's about it. Oh, and macros of course. compile-time evaluation was introduced in C++11 and expanded in subsequent versions of the language standard.
- qalmakka 4y agoAlso, `const` values in C are not really evaluated at compile time, because they have by default external linkage so they are not really "constant", they are more like "readonly" or 'let' in Rust. They are always loaded from memory, and that's why #define is still king in C. Doing const int X = 33; // ... void something() { int arr[X] = ... } works in both C and C++, but with a catch: in C++, X is evaluated at compile time (it has internal linkage), while in C this works only after C99 because it's actually a VLA.
- uecker 4y agoAlthough many compilers allow const int X = 33; enum { Y = X };
- qalmakka 4y agoThat's a GNU extension that everyone relies so much on it's basically akin to a standard. You get a warning from Clang (or an error from GCC) if you ask for a more "standard" interpretation of the source: $ clang -o cs cs.c -Wall -std=c11 -pedantic cs.c:6:6: warning: expression is not an integer constant expression; folding it to a constant is a GNU extension [-Wgnu-folding-constant] A = X, $ gcc -o cs cs.c -Wall -std=c11 cs.c:6:9: error: enumerator value for ‘A’ is not an integer constant 6 | A = X, | ^ In general, that's illegal ISO C and should always be rejected, but as you see that's not usually the case.
- mhh__ 4y agoYou might be able to do something truly arcane using GCC extensions and maybe the __attribute((error))__ thing but realistically it either won't compile or you won't notice unless it's too slow. The compiler constant folds fairly effectively anyway.
- rwmj 4y agoThis is what qemu uses: #define QEMU_BUILD_BUG_ON(x) \ typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused)); So you can write stuff like: QEMU_BUILD_BUG_ON(sizeof (struct foo) == 128); (for example if the struct is used for some network protocol and so it must be 128 bytes long).
- pm215 4y agoWe've switched to _Static_assert() now we can assume all our compilers support it: #define QEMU_BUILD_BUG_MSG(x, msg) _Static_assert(!(x), msg) #define QEMU_BUILD_BUG_ON(x) QEMU_BUILD_BUG_MSG(x, "not expecting: " #x)
- cesarb 4y agoThere is __builtin_constant_p (a GCC extension): https://gcc.gnu.org/onlinedocs/gcc-11.3.0/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fconstant_005fp https://gcc.gnu.org/onlinedocs/gcc-11.3.0/gcc/Other-Builtins... It's not exactly the same thing, but it's probably what you were thinking of.
- uecker 4y agoWhat do you want to use it for? C++ uses it for the compile-time programming together with templates. Essentially C++ evolves into a language where you write a program that gets interpreted at compile-time to produce some code that then gets compiled. But I am not sure this is a good idea. It adds a lot of complexity, places many responsibilities that belongs into a compiler onto library writers, increases compilation time a lot, and - with all template expansion - causes a lot of bloat that hurts performance. It also makes debugging interesting. But it looks really good in microbenchmarks because you can create optimal code for special cases easily, I just do not see how this translates into real world performance.
- jcelerier 4y agoIf it's not in the language it will be in separate preprocessors, which will all be strictly worse.
- xeeeeeeeeeeenu 4y agoI assume you're asking about a check for constness, like __is_constexpr() in Linux kernel. Starting with C11, it's possible to implement it without any non-standard extensions: https://stackoverflow.com/a/49480926 https://stackoverflow.com/a/49480926
- esgwpl 4y agoThis one? https://lore.kernel.org/lkml/1521584015.31174.3.camel@med.uni-goettingen.de/ https://lore.kernel.org/lkml/1521584015.31174.3.camel@med.un...