For some reason (related to performance measurements), I need to repeat a code segment 1000 times (1024 times would be OK too), but WITHOUT "for" or any other loop.
Obviously, I could most likely write a macro that would look something like this:
#define RUN_1000_TIMES(x) \
x \
x \
x \
...
... /* (999+1 times the same line) */
...
x \
x
... and than apply that macro to my code segment.
But is there a more elegant solution than 1000 lines long macro?
#define RUN_1024_TIMES(x) do {RUN_512_TIMES(x); RUN_512_TIMES(x); } while(0)
#define RUN_512_TIMES(x) do {RUN_256_TIMES(x); RUN_256_TIMES(x); } while(0)
#define RUN_256_TIMES(x) do {RUN_128_TIMES(x); RUN_128_TIMES(x); } while(0)
#define RUN_128_TIMES(x) do {RUN_64_TIMES(x); RUN_64_TIMES(x); } while(0)
#define RUN_64_TIMES(x) do {RUN_32_TIMES(x); RUN_32_TIMES(x); } while(0)
#define RUN_32_TIMES(x) do {RUN_16_TIMES(x); RUN_16_TIMES(x); } while(0)
#define RUN_16_TIMES(x) do {RUN_8_TIMES(x); RUN_8_TIMES(x); } while(0)
#define RUN_8_TIMES(x) do {RUN_4_TIMES(x); RUN_4_TIMES(x); } while(0)
#define RUN_4_TIMES(x) do {RUN_2_TIMES(x); RUN_2_TIMES(x); } while(0)
#define RUN_2_TIMES(x) do {x; x; } while(0)
the do{ ... } while(0) is only for the case that you call it with if (....) RUN_1024_TIMES(...);. You can remove it when you do not need it.
You could also do it with 3 times per macro:
#define RUN_1000_TIMES(x) do {RUN_729_TIMES(x); RUN_243_TIMES(x); RUN_27_TIMES(x); x; } while(0)
#define RUN_729_TIMES(x) do {RUN_243_TIMES(x); RUN_243_TIMES(x); RUN_243_TIMES(x); } while(0)
#define RUN_243_TIMES(x) do {RUN_81_TIMES(x); RUN_81_TIMES(x); RUN_81_TIMES(x); } while(0)
#define RUN_81_TIMES(x) do {RUN_27_TIMES(x); RUN_27_TIMES(x); RUN_27_TIMES(x); } while(0)
#define RUN_27_TIMES(x) do {RUN_9_TIMES(x); RUN_9_TIMES(x); RUN_9_TIMES(x); } while(0)
#define RUN_9_TIMES(x) do {RUN_3_TIMES(x); RUN_3_TIMES(x); RUN_3_TIMES(x); } while(0)
#define RUN_3_TIMES(x) do {x; x; x; } while(0)
in a Python file, put:
print("//header of the code")
for i in range(1000):
print("x;")
print("//bottom of the code")
and then:
./gen.py > file.c
that will be simpler that what ever you can do with the C preprocessor, that cannot perform things like a loop!
#define RUN_10_TIMES(X) X X X X X X X X X X
#define RUN_1000_TIMES(X) RUN_10_TIMES(RUN_10_TIMES(RUN_10_TIMES(X)))
Note that you get to recursively "call" a macro in "invocation" like syntax (so FOO(FOO(FOO(X))) is okay); this is because the first step of a function-like macro invocation uses argument substitution, which has no restrictions on recursion. Argument substitution specifically involves evaluating any argument whose corresponding parameter appears in a replacement list (and isn't stringified or part of a paste), as if it were on a line by itself, and then using the resulting expansion to replace each such parameter. After argument substitution (and paste/stringifications), the resulting replacement list is rescanned in a rescan and further replacement step; it's during this step that the macro is marked with "blue paint" (meaning, additional invocations are ignored). Invocation-like recursion is entirely a function of argument substitution, so it's allowed.
You can write your loops normally, and then just tell the compiler you want the loops to be unrolled. It's nicely written, and as optimal as if you wrote the 1000 lines.
The way to do this depends on your compiler. I'll write the answer for GCC which is the compiler I use normally, but other compilers should be similar.
If you want to unroll all loops in your code, it is easier: you just need to add an option or two to the command line:
-funroll-loops
-funroll-all-loops
If you want to know more about the behaviour of these options, refer to the compiler manual. There are also questions about them here on SO.
If you just want to unroll a specific loop, and keep all other loops, it is more difficult, but it can also be done. Check this SO answer for that: https://stackoverflow.com/a/14251545/6872717
You can use P99 for that: http://p99.gforge.inria.fr/p99-html/group__preprocessor__for_gaec0c87b336a5fa2a8230e207af5cc1f0.html#gaec0c87b336a5fa2a8230e207af5cc1f0
The "sad" part is that maybe a smart enough compiler... make it a loop!
Related
I know how to mark enums/functions as deprecated by using
__attribute__ ((deprecated)). But how can I mark constant macro
as deprecated?
#define MACRO1 4 //This is deprecated macro
GCC (and possibly others)
__attribute__((deprecated))
For your particular example with just a constant expression, you can use this:
Change
#define X (4)
to
#define X_old (4)
and then add
const int dep __attribute__((deprecated)) = 0;
#define X ((void)dep, X_old)
Addition also works:
#define X (X_old + dep)
For a procedure macro you can do this:
#define P_old do { ... } while(0)
#define P do { (void)dep; P_old; } while(0)
The only function of (void) is to suppress warnings. Thanks Kevin.
#pragma message
Another solution is to put all deprecated macros in a separate header file and use pragma. You could combine this with #ifdef and such:
#pragma message ("This header contains deprecated macros")
All compilers
Unreferenced label
Use an unreferenced label:
#define P_old do { ... } while(0)
#define P do { P_IS_DEPRECATED: P_old; } while(0)
This does not work for constant expression macros and requires you to compile with -Wall to get a warning. Will trigger error if used more than once.
Unused variable:
#define P_old do { ... } while(0)
#define P do { int P_IS_DEPRECATED; P_old; } while(0)
Does not work on constant expressions either. Also requires -Wall but can be used more than once.
Sidenote
Remember to encapsulate constant expression macros in parentheses. The macro #define X 2+3 would make an expression like 2*X to expand to 2*2+3 instead of 2*(2+3).
I have some macros that are defined based on compiler flags. I'm trying to decide whether I would rather have the macro defined as (void)0 or have it undefined and cause a compile time error.
i.e.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) (void)0
#endif
int main(void) {
...
PRINTF("something");
...
}
vs.
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#endif
int main(void) {
...
#ifdef DEBUG
PRINTF("something");
#endif
...
}
I'm not sure which technique I prefer. On one hand wrapping every PRINTF statement with #ifdef's would be ugly. On the other hand it would be nice to know at compile time if I've called a function that doesn't really work in the context.
I think the deciding factor will be whether or not having the (void)0 macros is going to affect the size of the executable.
When the code is compiled, what happens to the (void)0's? If PRINTF is defined as (void)0, does that mean the executable is going to contain some sort of (void)0 instruction or will it be completely ignored?
(void) 0;
is an expression statement with no side-effect. Any sane implementation will optimize this statement out (what else an implementation could do with such a statement?).
Having (void) 0 as a macro definition is endorsed by the C Standard as it appears in (C11) 7.2p1 for assert macro definition if NDEBUG is defined:
#define assert(ignore) ((void)0)
Note that defining:
#define PRINTF(...) (void)0
instead of
#define PRINTF(...)
has an advantage. In the first case, you have an expression (like a function that returns no value) and so it is usable for example in a comma expression or in a conditional expression.
For example:
// Comma expression
printf("test"), PRINTF("Hi Dennis");
// Conditional expression
test-expr ? perror("Hello") : PRINTF("world");
This two expression statements are only valid with the former PRINTF definition (with (void) 0).
It'll be completely ignored, you can confirm this by looking at the assembly output (gcc -S will generate file.s, the asm output), compare with and without the (void)0 line and see that it is completely the same.
A half way decent compiler will optimise away dead (unreachable) code, so you can:
#ifdef DEBUG
#define PRINTF(...) if (1) { printf(__VA_ARGS__) ; }
#else
#define PRINTF(...) if (0) { printf(__VA_ARGS__) ; }
#endif
which has the big advantage of allowing the compiler to check the debug code, no matter whether you are working with/without your DEBUG turned on -- which reduces the risk of ending up with painful teeth marks in your backside.
I was studying the Linux wireless subsystem code and noticed this code (in ieee80211_rx_handlers):
It first defines the macro:
#define CALL_RXH(rxh) \
do { \
res = rxh(rx); \
if (res != RX_CONTINUE) \
goto rxh_next; \
} while (0);
Then the macro is used to call a series of functions:
CALL_RXH(ieee80211_rx_h_check_more_data)
CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
CALL_RXH(ieee80211_rx_h_sta_process)
CALL_RXH(ieee80211_rx_h_decrypt)
CALL_RXH(ieee80211_rx_h_defragment)
CALL_RXH(ieee80211_rx_h_michael_mic_verify)
My question is, why not just call the functions directly like:
ieee80211_rx_h_check_more_data(rx);
ieee80211_rx_h_uapsd_and_pspoll(rx);
...
Is it just for the sake of outlining the code for easy reading?
Each use of the macro expands into the if check and goto, not just a single function call.
The if tests differ only by which function is called to produce the condition. Because the code would otherwise be repetitive, they used a macro to generate the boilerplate.
They could perhaps have interspersed calls res = xyz( rx ); with a macro expanding to the if … goto part, and then the macro would not take any parameter. How much gets encapsulated into the macro is a matter of code factoring style.
The do {} while(0) Macro could be easily used in condition block.
#define FUNC1() doing A; dong B;
#define FUNC2() do { doing A; doing B; } while(0)
We could use FUNC2() in if condition code block like this:
if (true)
FUNC2();
But FUNC1() could only be used like this:
if (true) {
FUNC1()
}
Currently, I have a scenario much like this:
#define my_macro(var) __builtin_types_compatible_p(typeof(var), foo) ? do_something : do_something_else
However, inadvertently the macro gets passed this parameter:
my_macro(int x);
Which of course fails, because typeof(int x) isn't valid.
Is there a transformation I can apply inside the my_macro which will allow typeof to work on that expression? I cannot change what is passed into the macro, only what happens inside the macro.
So, something like this:
#define my_macro(var) typeof(?? var ??)
Or, is there another expression I should be using here?
Well, I found a way to do it, using yet another GCC extension, this time the statement expression:
#define my_typeof(definition) typeof(({ definition, _def; _def; }))
Which, of course, expands to:
typeof(({ int x, _def; _def; }))
Pretty ugly, but why do I care? It works.
You could handle x or int x separately but to handle both with one macro you would need the ability to parse/separate a space-delimited argument within the C preprocessor. To my knowledge, no such support exists in the C preprocessor. Without such parsing capabilities you must find some other clever way to write a macro that works around this limitation, for example, something in the spirit of my_macro2() in the following code sample:
#include <stdio.h>
#define my_macro1(var) \
do { \
typeof(var) blah; \
printf("sizeof(var)=%d\n", sizeof(blah)); \
} while(0)
#define my_macro2(var) \
do { \
var, newvar_sametype; \
typeof(newvar_sametype) blah; \
printf("sizeof(newvar_sametype)=%d\n", sizeof(blah)); \
} while(0)
int
main()
{
int x;
my_macro1(x);
my_macro2(char y);
return 0;
}
I'd like to define a function like MACRO . i.e.
#define foo(x)\
#if x>32\
x\
#else\
(2*x)\
#endif
that is,
if x>32, then foo(x) present x
else, foo(x) present (2*x)
but my GCC complains about:
int a = foo(31);
I think C preprocessor should be handle this correctly. since at compile time, it knows x=33. it could replace foo(33) with (2*33)
You can as follows
#define foo(x) ((x) > 32 ? (x) : (2 * (x)))
But that evaluates x multiple times. You can instead create a static function, which is cleaner
static int foo(int x) {
if(x > 32)
return x;
return 2 * x;
}
Then you are also able to pass things to foo that have side effects, and have the side effect happen only one time.
What you have written is using the #if, #else and #endif preprocessor directives, but you need to use language constructs if you pass variables to the macro and want to evaluate their values. Using if, and else statements as in the actual language constructs don't work either, because control flow statements don't evaluate to values. In other words, an if statement is steering control flow only ("if A, then execute B, else execute C"), not evaluating to any values.
#define \
foo(x) \
({ \
int xx = (x); \
int result = (xx > 32) ? xx : (2*xx); \
result; \
})
int a = foo(31);
Expands out to
int a = if 31>32
31
else
(2*31)
endif;
That's how C macros work, via simple, dumb substitution. If you expect gcc to do anything more complex or intelligent with them, then your expectation is erroneous.
Given that, it's easy to see why your code won't work. An alternative that would suffice for this example would be:
#define foo(x) (x > 32 ? x : 2*x)
On the other hand, I would question whether macros are really the appropriate tool for such a thing to begin with. Just put it in the function and the compiler will inline the code if it thinks it will speed it up.
Consider:
int x = rand()
int y = foo( x );
x is not known at compile time.
The problem is not about the theory: provided that you, for some reason, want to have a macro that expands differently according to the value of a parameter passed to it, and this parameter is a constant, known to the macro preprocessor, there's no reason why it couldn't work... for a generic macro processor... But cpp unluckly does not allow the presence of other macro processor "commands" into a macro definition...
So your
#define foo(x) \
#if x>32 \
x \
#else \
2*x \
#endif
does not expand to
#if X>32
X
#else
2*X
#endif
where X is the known parameter (so change X to e.g. 31), which requires another pass by the preprocessor.
Moreover newlines are ignored, while they are important for such an use; otherwise, the following could be considered as a trick (that need another preprocessing pass however)
#define foo(x,y) \
y if x>32 \
x \
y else \
2*x \
y endif
that with foo(20,#) produces
# if 20>32 20 # else 2*20 # endif
which would work, if it would be
# if 20>32
20
# else
2*20
# endif
... but it is not (and as said, the output of the preprocessor must be feeded to the preprocessor again...)
So my answer is that if you need these things, you can't use the C preprocessor; you should use a uncommon (not standard?) C preprocessor, or just another macro processor, and if you need the sort of things that "cpp" has to "integrate" itself with C, then you can't use a generic one (like M4) so easily...