Is there a way to check at compile time if the argument of a macro is an integer literal, and evaluate the macro differently in that case?
#include <stdio.h> #define VALUE_0 0 #define VALUE_1 2 #define VALUE_2 4 #define VALUE_3 6 #define VALUE_4 8 #define VALUE(_idx_) VALUE_ ## _idx_ #define VALUE_(_idx_) 2*(_idx_) int main() { printf("%i\n", VALUE(3)); printf("%i\n", VALUE_(1+2)); } VALUE(3) is always resolved at compile-time, but only works if 3 is an integer literal. VALUE_(3) works for any argument type, but may be result in an expression that is computed at runtime (in a more complex case), and make compiler optimizations impossible.
If there a way to write the macro such that is automatically resolves to VALUE_ or to VALUE, depending if the argument is an integer literal.
Edit:
It is for a C program, or more specifically OpenCL C. It seems that for some OpenCL C compilers (for example NVidia nvcc and Intel), an expression like VALUE(idx) does not always get resolved at compile time, even when the argument is a constant. (Or at least the kernel does not get auto-vectorized if it contains such an expression.) For example if VALUE() resolves to a call of an inline function containing a switch statement, or to a lookup of a constant array, it does not work, but if it is an nested ?: expression, it works. VALUE_ would be guaranteed to resolve to a constant.
Because I'm generating C source code at runtime from the host and passing it to the OpenCL C compiler, it would be useful to not have to generate two different macros for each array.
constorconstexpr? Just because it's not a literal doesn't mean it isn't computed at compile time. Even in your example any sane compiler would compute1+2at compile time.VALUE_(3)is not already resolved at compile time? Converting2*(3)to6is fairly easy optimization for the compiler.