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...
Related
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!
I have a lot of lines of code like below:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
for each of them, I want to be able to extract (i-0) and pass it to another function. like:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
my_test_func(i-0);
so I wrote two macro:
#define GET_VERT(_x, _y, _z) get_vert(_x, _y, _z) , _y
#define SP_SETUP_POINT(_x, _y, _z) sp_setup_point(_x, _y); my_test_func(_z);
and call them like:
SP_SETUP_POINT( setup, GET_VERT(vertex_buffer, i-0, stride));
however, it does not give what I want, it expands to:
sp_setup_point(setup, get_vert(vertex_buffer, i-0, stride), i-0); my_test_func();
and MSVC compiler complains
not enough actual parameters for macro 'SP_SETUP_POINT'
I searched quite a bit, according to https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html
Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them
the argument are fully expanded, but the additional argument is not recognized. how it that ? any suggestion is appreciated.
The reason, IIRC, is that GET_VERT inside of an actual parameter list gets only expanded after the enclosing macro call is scanned. So the PP first wants to see the ")" at the end of the parameter list of SP_SETUP_POINT. In this process it recognizes that it is one parameter short of the declared form. One level of indirection helps, but beware, macro programming in C is strange and suffers from early bad implementation choices that no one ever dared to correct due to massive compatibility debt.
#define GET_VERT(_x, _y, _z) get_vert(_x, _y, _z) , _y
#define SP_SETUP_POINT(_x, expandme) SP_SETUP_POINT_(_x,expandme)
#define SP_SETUP_POINT_(_x,_y,_z) sp_setup_point(_x, _y); my_test_func(_z)
The last form is better written as
#define SP_SETUP_POINT_(_x,_y,_z) do{ sp_setup_point(_x, _y); my_test_func(_z); }while(0)
because writing sg. like
if (a==1) SP_SETUP_POINT(setup, GET_VERT(vertex_buffer, i-0, stride));
will lead to invisible errors in the control flow.
If I was going to tackle this, I think I'd start from the desired output:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
my_test_func(i-0);
You have 4 parameters: setup, vertex_buffer, expr, and stride, where expr is the i-0 parameter (which is itself a peculiar notation; how does that differ from i?). I might use those longer names in production-quality macros; I'm going to use short names a .. d here.
So, I'd design my macro from that starting point:
#define SP_SETUP_POINT(a, b, c, d) \
do { sp_setup_point((a), get_vert((b), (c), (d))); \
my_test_func(c); } while (0)
You could then invoke:
SP_SETUP_POINT(setup, vertex_buffer, i-0, stride);
This would generate the code you desire, even in a context such as:
if (x > y)
SP_SETUP_POINT(setup, vertex_buffer, i-0, stride);
else
SP_SETUP_POINT(setup, vertex_buffer, i+2, stride);
If you don't use the do { … } while (0) notation, then you have to use a comma operator to separate the function calls:
#define SP_SETUP_POINT(a, b, c, d) \
(sp_setup_point((a), get_vert((b), (c), (d))), \
my_test_func(c))
This evaluates to the return value from my_test_func(). There's no problem if you don't need to test the return value from sp_setup_point() — e.g. if it returns void anyway — and there's no problem if my_test_func() returns void.
You can also modify the macro to call MY_TEST_FUNC(c) and then conditionally define it:
#ifdef CALL_MY_TEST_FUNCTION
#define MY_TEST_FUNC(c) my_test_func(c)
#else
#define MY_TEST_FUNC(c) ((void)(c))
#endif
The advantage of evaluating c in the 'do not call' case is that the compiler ensures that c remains valid even as the code changes. Do not under-estimate the benefit of that in long-lived code.
This piece of code reports three misra c errors:
Inappropriate macro expansion
Function-like macro definition
Macro parameter with no parentheses
The original code is:
#define Wait(a, b) \
if (READ(b+0x1U)) \
{ \
while ((a & Write(b))) \
{ \
/* Do nothing - Busy wait */ \
} \
}
Here READ(b) is a macro and Write(b) is a function with no Misra C error.
I have trying changing it to remove errors
#define Wait(a, b) \
if ((uint32_t)0U != READ((b)+0x1U)) \
{ \
while ((uint32_t)0U != ((uint32_t)(a) & Write((uint32_t)(b)))) \
{ \
/* Do nothing - Busy wait */ \
} \
}
But i am still getting the first two errors. What needs to be done to remove these Misra C errors.
1.Inappropriate macro expansion
This is because you haven't encapsulated your macro properly. To fix this, you must change the code to:
#define Wait(a, b) \
\
do { \
if (READ(b+0x1U)) \
{ \
while ((a & Write(b))) \
{ \
/* Do nothing - Busy wait */ \
} \
} \
} while (0);
(But of course, this is pointless exercise if the rest of your code follows MISRA-C and always use {} after every if, for or while statement.)
2.Function-like macro definition
You are using a function-like macro. This isn't allowed by MISRA-C. Rewrite the macro as a function.
However, rule 19.7 is advisory, so you could in theory ignore it without raising a deviation. But there is no reason to do so in this case. There exists no reason why this need to be a macro and not a function.
3.Macro parameter with no parentheses
As you guessed, this has to do with every macro parameter being a potential sub-expression. Suppose someone calls your macro as Wait(x+y, z). Your code will then crash and burn upon encountering the while loop, because the macro will expand into while(x+y & Write(b)), which is the same thing as while(x + (y & Write(b)) ).
To solve this, surround every instance of a and b with parenthesis, as in your second example.
This piece of code reports three misra c errors:
You should report a bug to Klockwork, their tool is not working correctly. It should also have detected the following:
if (READ(b+0x1U)) violates rules 13.2. MISRA compliant code would be
if (READ(b+0x1U) != 0u)
while ((a & Write(b))) violates rule 13.2. MISRA compliant code would be
while ( (a & Write(b)) != 0u )
Non-MISRA related concerns:
(uint32_t)0U should preferably be written as 0UL or 0ul, which are more readable forms.
Frankly, this code was bad to begin with. Trying to make it MISRA-compliant as it stands, will turn it into a completely unreadable mess. Rewrite it from scratch instead:
void Wait (uint32_t a, uint32 b)
{
if( READ(b + 0x1u) != 0u ) /* comment here, explaining the code */
{
while ( (a & Write(b)) != 0u ) /* comment here, explaining the code */
{
; /* Do nothing - busy wait */
}
}
}
There's a list of things macros are allowed to expand to, and an if block isn't one of them. I believe this is because it can cause confusion about the attachment of else clauses. More about that here. You can use this construct:
#define MACRO(X) \
do { \
body here \
} while (0)
You should use a function instead of a function-like macro whenever you can. Without knowing what READ expands to I can't say if that's possible in this case. That would be the only way to get rid of the warning about that.
The third one you already figured out; you have to put parentheses around a and b in the body. The idea here is that if you have code like x*2 in the macro and someone passes 3+1 as x, without the parenthesis you'd get 3+1*2, which is 5, instead of (3+1)*2, which is the 8 which was almost certainly intended.
The only other thing I would have to say about your code is are you sure you want & there and not &&?
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;
}
let's say that I want to have C macro that works on any type.
I'm using GCC compiler (>= 4.6) and can use GNU99 macros.
//code...
any_type_t *retVal = function_that_runs_very_long_time(a, b, &&c, **d, &e, *f);
//other code...
usage of macro for TIMER can look for example like this
//code...
any_type_t *retVal =
TIMER(
function_that_runs_very_long_time(a, b, &&c, **d, &e, *f),
"TIMING FOR VALUE <%d, %d>", a, b
);
//other code...
So TIMER has to return value of given function and print duration of its run.
There is problem with functions that have void return type.
I can obviously have two macros like TIMER_TYPE and TIMER_VOID, but I want to use single one to time function with any return value.
Thank you for suggestions.
Edited example of this TIMER macro
#define TIMER(expr, fmt_msg, ...) \
({ \
struct timeval before, after; \
uint64_t time_span; \
int time_span_sec, time_span_usec; \
gettimeofday(&before, NULL); \
typeof(expr) _timer_expr__ = (expr); \ // <- static if?
gettimeofday(&after, NULL); \
time_span = (after.tv_sec * 1000000 + after.tv_usec) \
- (before.tv_sec * 1000000 + before.tv_usec); \
time_span_sec = time_span / 1000000; \
time_span_usec = time_span % 1000000; \
TRACE(fmt_msg "\n%s : %d.%d seconds", \
#expr, time_span_sec, time_span_usec, ...); \
_timer_expr__; \
})
What an interesting question, kudos!
After few experiments, I found a solution which uses __builtin_types_compatible_p and __builtin_choose_expr intrinsics of GCC.
__builtin_types_compatible_p
Quoting GCC manual:
Built-in Function: int __builtin_types_compatible_p (type1, type2)
You can use the built-in function __builtin_types_compatible_p to determine whether two types are the same.
This built-in function returns 1 if the unqualified versions of the types type1 and type2 (which are types, not expressions) are compatible, 0 otherwise. The result of this built-in function can be used in integer constant expressions.
This built-in function ignores top level qualifiers (e.g., const, volatile). For example, int is equivalent to const int.
So here is how we can check for "voidness".
#define __type_is_void(expr) __builtin_types_compatible_p(typeof(expr), void)
__builtin_choose_expr
Built-in Function: type __builtin_choose_expr (const_exp, exp1, exp2)
You can use the built-in function __builtin_choose_expr to evaluate code depending on the value of a constant expression. This built-in function returns exp1 if const_exp, which is an integer constant expression, is nonzero. Otherwise it returns exp2.
This built-in function is analogous to the ? : operator in C, except that the expression returned has its type unaltered by promotion rules. Also, the built-in function does not evaluate the expression that is not chosen. For example, if const_exp evaluates to true, exp2 is not evaluated even if it has side-effects.
If exp1 is returned, the return type is the same as exp1's type. Similarly, if exp2 is returned, its return type is the same as exp2.
So __builtin_choose_expr intrinsic is something like a "static switch" evaluated at compile-time.
Preparation
I don't paste here your TIMER macro, but I assume it is able to split it into two versions: one for void expr and one for the rest. Here are just stubs which evaluate the expression and yield the result of the same type.
#define __DO(expr) \
({ typeof(expr) __ret; __ret = (expr); __ret; })
#define __DO_VOID(expr) \
(void) (expr)
Naive solution
Now we can statically switch between two implementations, depending on the actual type of the expression. But in fact the naive solution doesn't work, see below.
#define DO(expr) \
__builtin_choose_expr(__type_is_void(expr), \
__DO_VOID(expr), \
__DO(expr)) # won't work
Attempt to compile this code passing a void expression gives the following error:
test.c:28:9: error: variable or field ‘__ret’ declared void
test.c:28:9: error: void value not ignored as it ought to be
Although __DO_VOID is chosen, __DO generates errors. This behavior is described in manual:
... the unused expression (exp1 or exp2 depending on the value of const_exp) may still generate syntax errors. This may change in future revisions.
Working solution
The trick is to substitute the original void expr with some non-void value to be able to compile the __DO case (which is anyway a dead code when expr is void).
#define __expr_or_zero(expr) __builtin_choose_expr(__type_is_void(expr), 0, (expr))
#define DO(expr) \
__builtin_choose_expr(__type_is_void(expr), \
__DO_VOID(expr), \
__DO(__expr_or_zero(expr))) # works fine!
That's it! Here is the complete source code on Ideone: http://ideone.com/EFy4pE
can you accept an answer of "this isn't really possible" ?
not the part about returning from a macro. but the part about conditionally testing expr for its return type.
in effect, you're asking for something like the following:
let's say instead of some magical check called "is_expr_type_void(expr)", you instead simply pass a 1 or a 0 at the time of the call to indicate is_void or !is_void in the following variation of your macro:
#define TIMER(is_void, expr, fmt_msg, ...) \
({ \
struct timeval before, after; \
uint64_t time_span; \
int time_span_sec, time_span_usec; \
gettimeofday(&before, NULL); \
if (is_void) \
(expr) \
else \
typeof(expr) _timer_expr__ = (expr); \ // <- static if?
gettimeofday(&after, NULL); \
time_span = (after.tv_sec * 1000000 + after.tv_usec) \
- (before.tv_sec * 1000000 + before.tv_usec); \
time_span_sec = time_span / 1000000; \
time_span_usec = time_span % 1000000; \
TRACE(fmt_msg "\n%s : %d.%d seconds", \
#expr, time_span_sec, time_span_usec, ...); \
if (!is_void) \
_timer_expr__; \
})
this simply cannot work. the preprocessor would create code for that if-else conditional in all cases, both void and non-void function calls. and both sides would compile fine for non-void functions. but the compiler would always choke on the "else" part of the conditional when TIMER is invoked with a void function … despite the fact that the code would never be called.
(now if there existed a really smart compiler that could both identify that it would be dead code and dead-strip it prior to flagging it as a compile time error, you'd be in luck! but i don't think gcc 4.6 is that smart … )
this leaves you with what would be a preferred option of a #if (is_void) conditional inside the #define. but that's simply not allowed. since, as this answer points out in attempting to answer a similar question about conditional preprocessing, the preprocessor is not turing-complete.
so … despite your desire to have a single macro, i think your simplest answer is to create one for void functions, and one for functions with return values.
As long as you've got typeof and _Generic, you can do also do it without __builtin_types_compatible_p or __builtin_choose_expr.
The caveat is that _Generic won't let you match void so instead of matching Expr against void, match (typeof(Expr)*){0} against void*.
Below is eldar-abusalimov example modified to use _Generic instead of __builtin_types_compatible_p and __builtin_choose_expr:
#include <stdio.h>
#define __type_is_void(expr) _Generic((typeof(expr)*){0}, void*:1, default:0)
#define __expr_or_zero(expr) _Generic((typeof(expr)*){0}, void*:0, default:(expr))
#define DO(expr) \
_Generic((typeof(expr)*){0}, \
void*:__DO_VOID(expr), \
default:__DO(__expr_or_zero(expr)))
#define __DO(expr) \
({ typeof(expr) __ret; puts("do nonvoid"); __ret = (expr); __ret; })
#define __DO_VOID(expr) \
(void)({ puts("do void"); (void)(expr); })
void foo(void) { }
int bar(void) { return 1; }
int main(void)
{
DO(foo());
DO(bar());
return 0;
}
If you really need to return from macro, use inline function instead.