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.