Checking if macro argument is literal - c

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.

I'd recommend always using the latter:
#define VALUE_(_idx_) 2*(_idx_)
If the argument is a constant or a constant expression, the resulting expression after the preprocessor will be evaluated by the compiler. If it is not, it will be evaluated at runtime.
The only difference between the two macros in the case of an integer literal is whether the preprocessor gives you the final result or whether the compiler does. In both cases, there is no runtime overhead, so better to go with the one that gives you the most flexibility.

I'll turn the problem on its head and suggest that you try forcing the compiler to compute the value (with the additional benefit of asserting that the value is, in fact, a compile-time constant):
#define MAKE_ME_CONSTANT(x) sizeof((struct{char c[x];}){{0}}.c)
This (tweaked from an earlier answer of mine) declares an anonymous structure with a char-array member whose size is your constant. It then instantiates it with a compound literal and retrieves the member's size. All of this is part of the unevaluated operand of a sizeof, so I expect any compiler to make it a constant.
Note: I didn't use the simpler sizeof(char[x]) because that could be a VLA. But VLAs can't be structure members, so we're good here.
Hence, you get:
#define VALUE(_idx_) MAKE_ME_CONSTANT(2*(_idx_))

Related

C MACRO evaluation

I wish to declare a statically allocated array.
Let's take a look at the following code:
#define MAX(a,b) ((a)>(b)?(a):(b))
#define FAST 16
#define SLOW 6
#define MAX_NUM MAX(FAST,SLOW)
U8* pBuffers[MAX_NUM];
When MAX_NUM being evaluated by the GCC compiler(FAST and SLOW are constants)?
I would like to make sure that MAX_NUM is constant and being evaluated as part of a compilation or by the pre-processor.
When you launch the compiler, the following phases are (sequentially) performed:
preprocessing: it manages #define, #ifdef / #endif...
code generation: it produces the machine code runnable on target CPU
optimization: it optimizes depending on user options
During the preprocessing phase, the preprocessor will for example "replace" your line with:
U8* pBuffers[MAX(FAST,SLOW)]
then:
U8* pBuffers[((FAST)>(SLOW)?(FAST):(SLOW))]
then finally:
U8* pBuffers[((16)>(6)?(16):(6))]
Indeed, the preprocessor is not very clever and does not go further.
During the code generation phase, your line will be interpreted as:
U8* pBuffers[16]
Because the code generator is very clever.
The C standard requires the sizes of most arrays to be declared using an integer constant expression, which can be, and in this case is required to be, fully evaluated at compile time. (The only exception is "variable length arrays", and those have to be function-local variables with "automatic storage duration" — not statically allocated.)
Therefore, one answer to your question is you don't have to worry about it. If you write
WHATEVER_TYPE variable[SOME EXPRESSION];
at file scope, either SOME EXPRESSION will be evaluated to a constant at compile time, or compilation will fail and you will get an error.
But a more useful answer is to explain how to see for yourself whether SOME EXPRESSION is an integer constant expression, when you are reading code. First, you have to mentally expand all of the macros. Then, you will presumably have an arithmetic expression of some sort (if not, it's a syntax error).
This arithmetic expression is a constant expression if it has no side-effects, doesn't make any function calls, and doesn't refer to the value of any variable (not even if it is const) (enum constants are fine, though, as are string literals, and sizeof variable as long as variable is completely declared and isn't a variable-length array). It is an integer constant expression if, in addition, it doesn't try to do any floating-point or pointer arithmetic (you are allowed to write a floating-point literal as the immediate operand of a cast, though; for instance ((int)3.1415926) is an integer constant expression).
So, to take your example,
#define MAX(a,b) ((a)>(b)?(a):(b))
#define FAST 16
#define SLOW 6
#define MAX_NUM MAX(FAST,SLOW)
U8* pBuffers[MAX_NUM];
after macro expansion we have
U8* pBuffers[((16)>(6)?(16):(6))];
The expression inside the square brackets has no side effects, doesn't make any function calls, doesn't refer to the value of any variable, and doesn't do any floating-point or pointer arithmetic, so it's an integer constant expression, and the compiler is required to evaluate it at compile time.
By contrast, if you were using this definition of MAX instead:
static inline size_t MAX(size_t a, size_t b)
{ return a > b ? a : b; }
then macro expansion would produce
U8* pBuffers[MAX(16, 8)];
and the expression inside the square brackets would be making a function call, so it wouldn't be an integer constant expression, or even a constant expression, and you would get a compile-time error.
(FYI, the rules in C++ are much more complicated; if you need to know about that, ask a new question.)
MACROS are always evaluated before the compilation process begins. So this code has nothing to worry about and it should work fine.
At the same time, this whole thing is the compiler dependent, I believe with gcc it will work fine. Maybe, for some bare-metal application, it may give a warning.

Correct definition of constants

I'm having a little trouble defining the constants I use in my code in a correct way. Although I read the excellent post Jonathan Leffler over at How do I use extern to share variables between source files?, I seem to have misunderstood something. This is the setup:
/* constants.h */
extern int NUM_PARTICLES;
extern int LIGHTSPEED;
This header is used in random.h and main.c, which looks like
#include "constants.h"
int NUM_PARTICLES=104;
in random.h or
#include "constants.h"
int LIGHTSPEED=104;
in main.c, respectively. NUM_PARTICLES is used in main.c in
30: double ghosts[NUM_PARTICLES][4];
31: double output[NUM_PARTICLES][3];
Although this thing works, I get the following warnings,
main.c: In function ‘int main()’:
main.c:30:32: warning: ISO C++ forbids variable length array ‘ghosts’ [-Wvla]
main.c:31:32: warning: ISO C++ forbids variable length array ‘output’ [-Wvla]
which is weird, because in my opinion I do give the array a constant value that is known at compilation time. (And usually these array length errors cause some segfaults, which in this case they do not.) Any ideas?
Short story: this is a quirk of C.
Normally, you would define an integer constant as
const int LIGHTSPEED = 104;
The problem is that according to the language rules this constant is not a constant expression, and thus cannot be used to specify the size of a statically allocated array.
The relevant part of the C standard (6.6/6, I am not making this up) defines what an integer constant expression is:
An integer constant expression shall have integer type and shall
only have operands that are integer constants, enumeration constants,
character constants, sizeof expressions whose results are integer
constants, and floating constants that are the immediate operands of
casts.
There are two solutions for this. The classic one is to use a macro, which simply pastes 104 between the angle brackets before the compiler sees the code, therefore making the array size an integer constant:
#define NUM_PARTICLES 104
The better one (IMO) is to avoid a macro because you can, and use an enum, which is possible (you are using an enumeration constant):
enum { NUM_PARTICLES = 104 };

How to check if a parameter is an integral constant expression in a C preprocessor macro?

I'm currently cleaning up an existing C-library to publish it shamelessly.
A preprocessor macro NPOT is used to calculate the next greater power of two for a given integral constant expression at compile time. The macro is normally used in direct initialisations. For all other cases (e.g. using variable parameters), there is an inline function with the same function.
But if the user passes a variable, the algorithm expands to a huge piece of machine code. My question is:
What may I do to prevent a user from passing anything but an integral constant expression to my macro?
#define NPOT(x) complex_algorithm(x)
const int c=10;
int main(void) {
int i=5;
foo = NPOT(5); // works, and does everything it should
foo = NPOT(c); // works also, but blows up the code extremely
foo = NPOT(i); // blows up the code also
}
What I already tried:
Define the macro to #define NPOT(x) complex_algorithm(x ## u). It still works and throws a - even if hardly helpful - compiler error for variable parameters. Unless there is no variable like iu... Dirty, dangerous, don't want it.
Documentation, didn't work for most users.
You can use any expression that needs a constant integral expression and that will then be optimized out.
#define NPOT(X) \
(1 \
? complex_algorithm(X) \
: sizeof(struct { int needs_constant[1 ? 1 : (X)]; }) \
)
eventually you should cast the result of the sizeof to the appropriate integer type, so the return expression is of a type that you'd expect.
I am using an untagged struct here to
have a type so really no temporary is produced
have a unique type such that the expression can be repeated anywhere in the code without causing conflicts
trigger the use of a VLA, which is not allowed inside a struct as of C99:
A member of a structure or union may have any object type other than a
variably modified type.
I am using the ternary ?: with 1 as the selecting expression to ensure that the : is always evaluated for its type, but never evaluated as an expression.
Edit: It seems that gcc accepts VLA inside struct as an extension and doesn't even warn about it, even when I explicitly say -std=c99. This is really a bad idea of them.
For such a weird compiler :) you could use sizeof((int[X]){ 0 }), instead. This is "as forbidden" as the above version, but additionally even gcc complains about it.
#define INTEGRAL_CONST_EXPR(x) ((void) sizeof (struct {int a:(x);}), (x))
This will give a compile error if x is not a integral constant expression.
my_function(INTEGRAL_CONST_EXPR(1 + 2 + 3)); // OK
my_function(INTEGRAL_CONST_EXPR(1.0 + 2 + 3)); // compile error
Note that this solution does not work for initializing a static variable:
static int a = INTEGRAL_CONST_EXPR(2 + 3);
will trigger a compile error because of an expression with , is not a constant expression.
As #JensGustedt put in the comment, an integral constant expression resolving to a negative integer number cannot be used in this solution as bit-field width cannot be negative.

How to verify a type in a C macro

I have been thinking about ways to validate types in C macros and so far the best way that I have come up with is this:
#define ASSERT_PTYPE(TYPE, VALUE) (0 && (*(int (*)(TYPE*))0)(VALUE))
This obviously expects a type name and a pointer to that type. A similar ASSERT_TYPE macro can be made as well. This seems to work quite well with GCC. It even gives a very helpful error message in the case that the types do not match. The problems are that I am not completely certain that this is valid C or the best way for that matter.
As I understand it the standard says that you can cast a function pointer, but the result of calling the cast function pointer is undefined. In this case it is impossible for the function to be called at runtime. Is that good enough or does the standard mean that you cannot even write code that cannot be called that calls the cast function?
With C99 and compound literals you can do something like
#define ASSERT_TYPE(TYPE, VALUE) ((TYPE){ 0 } = (VALUE))
This ensures that VALUE is assignment compatible to TYPE. The expression returns an rvalue because of the assignment.
Compound literals work in function scope as well as in file scope and any decent compiler should optimize the extra object that is created out of the way.
Addition: TYPE in that macro can be any valid type name, e.g pointer double*, struct or union struct toto, besides arrays. Array type such as double[4] wouldn't work because of the assignment. Use pointer to
array double(*)[4] instead, e.g as in
double A[4];
(*ASSERT_TYPE(double(*)[4], &A))
where the second line again is a lvalue of type double[4] that is compile time checked for that property.

Pointer to #define

I was just curious to know if it is possible to have a pointer referring to #define constant. If yes, how to do it?
The #define directive is a directive to the preprocessor, meaning that it is invoked by the preprocessor before anything is even compiled.
Therefore, if you type:
#define NUMBER 100
And then later you type:
int x = NUMBER;
What your compiler actually sees is simply:
int x = 100;
It's basically as if you had opened up your source code in a word processor and did a find/replace to replace each occurrence of "NUMBER" with "100". So your compiler has no idea about the existence of NUMBER. Only the pre-compilation preprocessor knows what NUMBER means.
So, if you try to take the address of NUMBER, the compiler will think you are trying to take the address of an integer literal constant, which is not valid.
No, because #define is for text replacement, so it's not a variable you can get a pointer to -- what you're seeing is actually replaced by the definition of the #define before the code is passed to the compiler, so there's nothing to take the address of. If you need the address of a constant, define a const variable instead (C++).
It's generally considered good practice to use constants instead of macros, because of the fact that they actually represent variables, with their own scoping rules and data types. Macros are global and typeless, and in a large program can easily confuse the reader (since the reader isn't seeing what's actually there).
#define defines a macro. A macro just causes one sequence of tokens to be replaced by a different sequence of tokens. Pointers and macros are totally distinct things.
If by "#define constant" you mean a macro that expands to a numeric value, the answer is still no, because anywhere the macro is used it is just replaced with that value. There's no way to get a pointer, for example, to the number 42.
No ,It's Not possible in C/C++
You can use the #define directive to give a meaningful name to a constant in your program
We can able to use in two forms.
Please : See this link
http://msdn.microsoft.com/en-us/library/teas0593%28VS.80%29.aspx
The #define directive can contain an object-like definition or a function-like definition.
Iam sorry iam unable to provide one more wink ... Please see the IBM links..since below i pasted linke link
u can get full info from above 2 links
There is a way to overcome this issue:
#define ROW 2
void foo()
{
int tmpInt = ROW;
int *rowPointer = &tmpInt;
// ...
}
Or if you know it's type you can even do that:
void getDefinePointer(int * pointer)
{
*pointer = ROW;
}
And use it:
int rowPointer = NULL;
getDefinePointer(&rowPointer2);
printf("ROW==%d\n", rowPointer2);
and you have a pointer to #define constant.

Resources