Evaluate macro parameter only once - c

I need to write a macro which traps any invalid index i for an array of length n. Here is what I got so far:
#define TRAP(i, n) (((unsigned int) (i) < (n))? (i): (abort(), 0))
The problem with this definition, however, is that the index expression i is evaluated twice; in the expression a[TRAP(f(), n)], for instance, f may have a side effect or take a long time to execute. I cannot introduce a temporary variable since the macro needs to expand to an expression. Also, defining TRAP as an ordinary function implies a run-time overhead and makes it harder for the compiler to optimize away the trap.
Is there a way to rewrite TRAP so that i is evaluated only once?
Edit: I'm using ANSI C89

You can evaluate once, and use the result, by doing something like this:
#define TRAP2(i, n) ({unsigned int _i = (i); _i < (n)? _i: (abort(), 0);})
This is a gcc specific solution, that will compile when used as the RHS of an assignment. It defines a (very) local variable, which might hide a prior definition of another variable, but that doesn't matter, as long as you don't try to use the prior version in the macro. But as people say, why do this in the first place?

Use the macro TRAP when the index expression doesn't contain a function call and use a (non-macro) function trap when it does. This way the function call overhead only occurs in the rarer latter case.

Related

Programmatically determine if a variable's value was computed at compile time or at run time

Is there a way in C to programmatically determine that variable's value was computed at compile time or at run time?
Example:
const double a = 2.0;
const double b = 3.0;
double c1 = a / b; // done at compile time (constant folding / propagation)
double c2 = *(volatile double*)&a / *(volatile double*)&b; // done at run time
compute_time_t c1_ct = compute_time(c1);
compute_time_t c2_ct = compute_time(c2);
assert(c1_ct == COMPILE_TIME);
assert(c2_ct == RUN_TIME);
In C (as in, defined by the language standard), no, there is no way.
There are however compiler-specific ways using which you can get really close to achieving what you want. The most famous, as #Nate Eldredge notes in the comments, is the builtin function __builtin_constant_p() available in GCC and Clang.
Here's the relevant excerpt from the GCC doc:
Built-in Function: int __builtin_constant_p (exp)
You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile time and hence that GCC can perform constant-folding on expressions involving that value. The argument of the function is the value to test. The function returns the integer 1 if the argument is known to be a compile-time constant and 0 if it is not known to be a compile-time constant. A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the -O option.
Note that this function does not guarantee to detect all compile-time constants, but only the ones that GCC is able to prove as such. Different optimization levels might change the result returned by this function.
This built-in function is widely used in glibc for optimization purposes (example), and usually the result is only trusted when it's 1, assuming a non-constant otherwise:
void somefunc(int x) {
if (__builtin_constant_p(x)) {
// Perform optimized operation knowing x is a compile-time constant.
} else {
// Assume x is not a compile-time constant.
}
}
Using your own example:
const double a = 2.0;
const double b = 3.0;
double c1 = a / b; // done at compile time (constant folding / propagation)
double c2 = *(volatile double*)&a / *(volatile double*)&b; // done at run time
assert(__builtin_constant_p(c1));
assert(!__builtin_constant_p(c2));
You ask,
Is there a way in C to programmatically determine that variable's
value was computed at compile time or at run time?
No, there is no way to encode such a determination into the source of a strictly conforming C program.
Certainly C does not require values to be tagged systematically in a way that distinguishes among them based on when they were computed, and no C implementation I have ever heard of or imagined does that, so such a determination cannot be based on the values of the expressions of interest. Furthermore, all C function arguments are passed by value, so the hypothetical compute_time() cannot be implemented as a function because values are all it would have to work with.
compute_time() also cannot be a macro, because macros can work only with (preprocessing) tokens, for example the identifiers c1 and c2 in your example code. Those are opaque to the preprocessor; it knows nothing about values attributed to them when they are evaluated as expressions according to C semantics.
And there is no operator that serves the purpose.
Standard C provides no other alternatives, so if the question is about the C language and not any particular implementation of it then that's the end of the story. Moreover, although it is conceivable that a given C implementation would provide your compute_time() or a functional equivalent as an extension, I am unaware of any that do. (However, see #MarcoBonelli's answer, for an example of a similar, but not identical, extension.)

Is it safe to use foo() && 0 in C?

Imagine i have the following piece of C-code where foo() produces a side effect and returns an integer:
if(bar) {
foo();
return 0;
}
Now, say I really like making my code compact, possibly at the reader's expense, and I change it into this:
if (bar)
return foo() && 0;
Can I be sure these two pieces of code will produce the same behavior, or would I risk the call to foo() not being executed due to possible compiler optimizations or something like that, thus not producing the desired side-effect?
NOTE: This is not a question about which piece of code is better, but whether the two pieces actually produce the same behavior in all cases. I think the majority (and I) can agree that the former piece of code should be used.
Yes, those two are the same. foo() will always be called (assuming bar is true).
The two forms you give are equivalent. The C11 standard (draft n1570) states,
6.5.13 Logical AND operator
...
Semantics
3 The && operator shall yield 1 if both of its operands compare unequal to 0;
otherwise, it yields 0. The result has type int.
4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right
evaluation; if the second operand is evaluated, there is a sequence point between
the evaluations of the first and second operands. If the first operand compares
equal to 0, the second operand is not evaluated.
Similar language appeared in all C standards so far.
You should probably prefer using the comma operator here (return foo(), 0;) because:
It's shorter (one character versus two for the operator, and you can get away with removing the left space character when using a comma, for a total of two fewer characters).
It gives you more flexibility, as you can return non-scalar types (such as structs), and a wider range of integers than just 0 or 1.
It conveys the intent better: "Discard return value of foo() and return something else (0) instead".
Now if you do chance upon a compiler that deletes the call to foo(), then either the compiler managed to prove that foo() is a function with no visible side-effects, or more likely it has a serious bug and you should report it.
Why obfuscate your code in the latter?
Use the former.
Easier to read i.e. this is easier to understand
if(bar) {
foo();
return 0;
}
Or unless got a problem with job security

Expansion of module_param() macro: a struct with a single member or a bitfield? [duplicate]

I bumped into this strange macro code in /usr/include/linux/kernel.h:
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
What does :-!! do?
This is, in effect, a way to check whether the expression e can be evaluated to be 0, and if not, to fail the build.
The macro is somewhat misnamed; it should be something more like BUILD_BUG_OR_ZERO, rather than ...ON_ZERO. (There have been occasional discussions about whether this is a confusing name.)
You should read the expression like this:
sizeof(struct { int: -!!(e); }))
(e): Compute expression e.
!!(e): Logically negate twice: 0 if e == 0; otherwise 1.
-!!(e): Numerically negate the expression from step 2: 0 if it was 0; otherwise -1.
struct{int: -!!(0);} --> struct{int: 0;}: If it was zero, then we declare a struct with an anonymous integer bitfield that has width zero. Everything is fine and we proceed as normal.
struct{int: -!!(1);} --> struct{int: -1;}: On the other hand, if it isn't zero, then it will be some negative number. Declaring any bitfield with negative width is a compilation error.
So we'll either wind up with a bitfield that has width 0 in a struct, which is fine, or a bitfield with negative width, which is a compilation error. Then we take sizeof that field, so we get a size_t with the appropriate width (which will be zero in the case where e is zero).
Some people have asked: Why not just use an assert?
keithmo's answer here has a good response:
These macros implement a compile-time test, while assert() is a run-time test.
Exactly right. You don't want to detect problems in your kernel at runtime that could have been caught earlier! It's a critical piece of the operating system. To whatever extent problems can be detected at compile time, so much the better.
The : is a bitfield. As for !!, that is logical double negation and so returns 0 for false or 1 for true. And the - is a minus sign, i.e. arithmetic negation.
It's all just a trick to get the compiler to barf on invalid inputs.
Consider BUILD_BUG_ON_ZERO. When -!!(e) evaluates to a negative value, that produces a compile error. Otherwise -!!(e) evaluates to 0, and a 0 width bitfield has size of 0. And hence the macro evaluates to a size_t with value 0.
The name is weak in my view because the build in fact fails when the input is not zero.
BUILD_BUG_ON_NULL is very similar, but yields a pointer rather than an int.
Some people seem to be confusing these macros with assert().
These macros implement a compile-time test, while assert() is a runtime test.
Well, I am quite surprised that the alternatives to this syntax have not been mentioned. Another common (but older) mechanism is to call a function that isn't defined and rely on the optimizer to compile-out the function call if your assertion is correct.
#define MY_COMPILETIME_ASSERT(test) \
do { \
extern void you_did_something_bad(void); \
if (!(test)) \
you_did_something_bad(void); \
} while (0)
While this mechanism works (as long as optimizations are enabled) it has the downside of not reporting an error until you link, at which time it fails to find the definition for the function you_did_something_bad(). That's why kernel developers starting using tricks like the negative sized bit-field widths and the negative-sized arrays (the later of which stopped breaking builds in GCC 4.4).
In sympathy for the need for compile-time assertions, GCC 4.3 introduced the error function attribute that allows you to extend upon this older concept, but generate a compile-time error with a message of your choosing -- no more cryptic "negative sized array" error messages!
#define MAKE_SURE_THIS_IS_FIVE(number) \
do { \
extern void this_isnt_five(void) __attribute__((error( \
"I asked for five and you gave me " #number))); \
if ((number) != 5) \
this_isnt_five(); \
} while (0)
In fact, as of Linux 3.9, we now have a macro called compiletime_assert which uses this feature and most of the macros in bug.h have been updated accordingly. Still, this macro can't be used as an initializer. However, using by statement expressions (another GCC C-extension), you can!
#define ANY_NUMBER_BUT_FIVE(number) \
({ \
typeof(number) n = (number); \
extern void this_number_is_five(void) __attribute__(( \
error("I told you not to give me a five!"))); \
if (n == 5) \
this_number_is_five(); \
n; \
})
This macro will evaluate its parameter exactly once (in case it has side-effects) and create a compile-time error that says "I told you not to give me a five!" if the expression evaluates to five or is not a compile-time constant.
So why aren't we using this instead of negative-sized bit-fields? Alas, there are currently many restrictions of the use of statement expressions, including their use as constant initializers (for enum constants, bit-field width, etc.) even if the statement expression is completely constant its self (i.e., can be fully evaluated at compile-time and otherwise passes the __builtin_constant_p() test). Further, they cannot be used outside of a function body.
Hopefully, GCC will amend these shortcomings soon and allow constant statement expressions to be used as constant initializers. The challenge here is the language specification defining what is a legal constant expression. C++11 added the constexpr keyword for just this type or thing, but no counterpart exists in C11. While C11 did get static assertions, which will solve part of this problem, it wont solve all of these shortcomings. So I hope that gcc can make a constexpr functionality available as an extension via -std=gnuc99 & -std=gnuc11 or some such and allow its use on statement expressions et. al.
It's creating a size 0 bitfield if the condition is false, but a size -1 (-!!1) bitfield if the condition is true/non-zero. In the former case, there is no error and the struct is initialized with an int member. In the latter case, there is a compile error (and no such thing as a size -1 bitfield is created, of course).

What is ":-!!" in C code?

I bumped into this strange macro code in /usr/include/linux/kernel.h:
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
What does :-!! do?
This is, in effect, a way to check whether the expression e can be evaluated to be 0, and if not, to fail the build.
The macro is somewhat misnamed; it should be something more like BUILD_BUG_OR_ZERO, rather than ...ON_ZERO. (There have been occasional discussions about whether this is a confusing name.)
You should read the expression like this:
sizeof(struct { int: -!!(e); }))
(e): Compute expression e.
!!(e): Logically negate twice: 0 if e == 0; otherwise 1.
-!!(e): Numerically negate the expression from step 2: 0 if it was 0; otherwise -1.
struct{int: -!!(0);} --> struct{int: 0;}: If it was zero, then we declare a struct with an anonymous integer bitfield that has width zero. Everything is fine and we proceed as normal.
struct{int: -!!(1);} --> struct{int: -1;}: On the other hand, if it isn't zero, then it will be some negative number. Declaring any bitfield with negative width is a compilation error.
So we'll either wind up with a bitfield that has width 0 in a struct, which is fine, or a bitfield with negative width, which is a compilation error. Then we take sizeof that field, so we get a size_t with the appropriate width (which will be zero in the case where e is zero).
Some people have asked: Why not just use an assert?
keithmo's answer here has a good response:
These macros implement a compile-time test, while assert() is a run-time test.
Exactly right. You don't want to detect problems in your kernel at runtime that could have been caught earlier! It's a critical piece of the operating system. To whatever extent problems can be detected at compile time, so much the better.
The : is a bitfield. As for !!, that is logical double negation and so returns 0 for false or 1 for true. And the - is a minus sign, i.e. arithmetic negation.
It's all just a trick to get the compiler to barf on invalid inputs.
Consider BUILD_BUG_ON_ZERO. When -!!(e) evaluates to a negative value, that produces a compile error. Otherwise -!!(e) evaluates to 0, and a 0 width bitfield has size of 0. And hence the macro evaluates to a size_t with value 0.
The name is weak in my view because the build in fact fails when the input is not zero.
BUILD_BUG_ON_NULL is very similar, but yields a pointer rather than an int.
Some people seem to be confusing these macros with assert().
These macros implement a compile-time test, while assert() is a runtime test.
Well, I am quite surprised that the alternatives to this syntax have not been mentioned. Another common (but older) mechanism is to call a function that isn't defined and rely on the optimizer to compile-out the function call if your assertion is correct.
#define MY_COMPILETIME_ASSERT(test) \
do { \
extern void you_did_something_bad(void); \
if (!(test)) \
you_did_something_bad(void); \
} while (0)
While this mechanism works (as long as optimizations are enabled) it has the downside of not reporting an error until you link, at which time it fails to find the definition for the function you_did_something_bad(). That's why kernel developers starting using tricks like the negative sized bit-field widths and the negative-sized arrays (the later of which stopped breaking builds in GCC 4.4).
In sympathy for the need for compile-time assertions, GCC 4.3 introduced the error function attribute that allows you to extend upon this older concept, but generate a compile-time error with a message of your choosing -- no more cryptic "negative sized array" error messages!
#define MAKE_SURE_THIS_IS_FIVE(number) \
do { \
extern void this_isnt_five(void) __attribute__((error( \
"I asked for five and you gave me " #number))); \
if ((number) != 5) \
this_isnt_five(); \
} while (0)
In fact, as of Linux 3.9, we now have a macro called compiletime_assert which uses this feature and most of the macros in bug.h have been updated accordingly. Still, this macro can't be used as an initializer. However, using by statement expressions (another GCC C-extension), you can!
#define ANY_NUMBER_BUT_FIVE(number) \
({ \
typeof(number) n = (number); \
extern void this_number_is_five(void) __attribute__(( \
error("I told you not to give me a five!"))); \
if (n == 5) \
this_number_is_five(); \
n; \
})
This macro will evaluate its parameter exactly once (in case it has side-effects) and create a compile-time error that says "I told you not to give me a five!" if the expression evaluates to five or is not a compile-time constant.
So why aren't we using this instead of negative-sized bit-fields? Alas, there are currently many restrictions of the use of statement expressions, including their use as constant initializers (for enum constants, bit-field width, etc.) even if the statement expression is completely constant its self (i.e., can be fully evaluated at compile-time and otherwise passes the __builtin_constant_p() test). Further, they cannot be used outside of a function body.
Hopefully, GCC will amend these shortcomings soon and allow constant statement expressions to be used as constant initializers. The challenge here is the language specification defining what is a legal constant expression. C++11 added the constexpr keyword for just this type or thing, but no counterpart exists in C11. While C11 did get static assertions, which will solve part of this problem, it wont solve all of these shortcomings. So I hope that gcc can make a constexpr functionality available as an extension via -std=gnuc99 & -std=gnuc11 or some such and allow its use on statement expressions et. al.
It's creating a size 0 bitfield if the condition is false, but a size -1 (-!!1) bitfield if the condition is true/non-zero. In the former case, there is no error and the struct is initialized with an int member. In the latter case, there is a compile error (and no such thing as a size -1 bitfield is created, of course).

C non-trivial constants

I want to make several constants in C with #define to speed up computation. Two of them are not simply trivial numbers, where one is a right shift, the other is a power. math.h in C gives the function pow() for doubles, whereas I need powers for integers, so I wrote my own function, ipow, so I wouldn't need to be casting everytime.
My question is this: One of the #define constants I want to make is a power, say ipow(M, T), where M and T were also #define constants. ipow is a function in the actual code, so this actually seems to slows things down when I run the code (is it running ipow everytime the constant is mentioned?). However, when I ues the built in pow function and just do (int)pow(M,T), the code is sped up. I'm confused as to why this is, since the ipow and pow functions are just as fast.
On a more general note, can I define constants using #define using functions inside the actual code? The above example has me confused on whether this speeds things up or actually slows things down.
(int)pow(M,T) is faster than using your function ipow, because if they are doing the same, then ipow is as fast but with the overhead of calling it (pushing arguments, etc.).
Also, yes, if you #define it in this way, ipow / pow / whatever is called every time; the preprocessor has no idea about what it is doing; it's basically string replacing. Therefore, your constant is simply being replaced by the text ipow(M,T) and so it is calculated everytime you need your constant.
Finally, for your case, a solution might be to use a global variable instead of a #define constant for your constant. This way, you can compute it once at the beginning of your program, and then use it later (without any more computations of it).
You don't need C++ to do metaprogramming. If you have a C99 compatible C compiler and preprocessor you can use P99 with something like the following
#include "p99_for.h"
#define P00_POW(NAME, I, REC, Y) (NAME) * (REC)
#define IPOW(N, X) (P99_FOR(X, N, P00_POW, P00_NAM, P99_REP(N,)))
For example IPOW(4, A) is then expanded to ((A) * ((A) * ((A) * (A)))). The only things that you should watch are
N must be (or expand to) a plain decimal constant with no suffix such as U or L
X should not have side effects
since it is evaluated several times
Yes, ipow is getting run every time the constant is mentioned. The C preprocessor is simply replacing all mentions of the constant with what you #define'd it as.
EDIT:
If you really want to compute these integers at compile time, you could try using Template Metaprogramming. This requires C++, however.
I don't think this is possible with c pre-possessor , because it doesn't support recursion.
(you can use template meta-programming if you are using c++)
I suspect that (int)pow(M,T) is faster than using (int)ipow(M,T) because the compiler has special knowledge of the pow() function (as an intrinsic). I wouldn't be surprised if given constant arguments that it elides the function call altogether when pow() is used.
However, since it has no special knowledge of ipow(), it doesn't do the same, and ends up actually calling the function.
You should be able to verify whether or not this is happening by looking at the assembly generated in a debugger or by having the compiler create an assembly listing. If that's what's happening, and your ipow() function is nothing more than a call to pow() (casting the result to an int), you might be able to convince your compiler to perform the same optimization for ipow() by making it an inline function.
Your ipow isn't faster since its just a simple call to a function.
Also I'm aware of compiler optimisation for standard C library routines and math functions.
Most possible the compiler is capable of determining the constexpr parameters and calculate the value of the #define at compile time.
Internally they will be replaced to some thing like this where the exponent is constant.
#define pow2(x) ( (x) * (x) )
#define pow3(x) ( (x) * (x) * (x) )
#define pow4(x) ( pow2(x) * pow2(x) )
#define pow5(x) ( pow4(x) * (x) )
#define pow6(x) ( pow3(x) * pow3(x) )
...
The only work around is to use C++ metta programming to get better run time performance.
template<class T, T base, T exp>
struct ipow
{
static const T value = base * ipow<T, base, exp - 1>::value;
};
template<class T, T base>
struct ipow<T, base, 0>
{
static const T value = 1;
};
you would use the above struct as follows:
ipow<size_t, M, T>::value
The C preprocessor will not evaluate a function call to a C function such as ipow or pow at compile time, it merely does text replacement.
The preprocessor does have a concept of function-like macros, however these are not so much 'evaluated' as text replaced. It would be temping to think you could write a recursive function-like macro to self-multiply a constant to raise it to a power, but in fact you can't - due to the non-evaluation of macro bodies, you won't actually get continually recursive calculation when the macro refers to itself.
For your shift operation, a #define involving constants and the shift operator will get text replaced by the preprocessor, but the constant expression will get evaluated during compilation, so this is efficient. In fact it's very common in hardware interfaces, ie #define UART_RXD_READY ( 1 << 11 ) or something like that

Resources