[ACCEPTED]-Using defined(MACRO) inside the C if statement-c-preprocessor
A macro by comex is expanded to 1 if the argument 21 is defined to 1. Otherwise it is expanded 20 to 0:
#define is_set(macro) is_set_(macro)
#define macrotest_1 ,
#define is_set_(value) is_set__(macrotest_##value)
#define is_set__(comma) is_set___(comma 1, 0)
#define is_set___(_, v, ...) v
You can use it as follows:
if (is_set(MACRO)) {
/* Do something when MACRO is set */
}
Explanation:
The 19 trick is based on variadic function-like 18 macros (...
) and preprocessor token concatenation 17 (##
).
is_set
is simply a wrapper to facilitate the expansion of its parameter.is_set_
tries to concatenatemacrotest_
with the evaluated 16 value of its input (comma
). If its input is defined, then 15 this works; otherwiseis_set__
is called withmacrotest_<macro>
where 14<macro>
is the original argument tois_set
(e.g.,is_set(foo)
leads 13 tomacrotest_foo
iffoo
is not a defined macro).In
is_set__
its 12 parameter is again expanded but this only 11 works out if it is passedmacrotest_1
. If it is, then 10is_set___(, 1, 0)
is called becausecomma
evaluates to,
(note 9 the 3 parameters!). For any other value 8 of comma (i.e., if the macro to be tested 7 is undefined or has any other (expanded) value 6 than1
the parameter can not be expanded 5 and thusis_set___(macrotest_<macro> 1, 0)
is called, which has only 2 arguments.Eventually,
is_set___
simply 4 selects its second parameter for its "output" and 3 drops everything else. Due to the behavior 2 ofis_set__
this leads to either1
if the macro to 1 be tested is defined and 1, or0
otherwise.
Ok, based on the previous post I got this 6 idea, which seems to work:
#define DEFINEDX(NAME) ((#NAME)[0] == 0) #define DEFINED(NAME) DEFINEDX(NAME)
This will check 5 if NAME is defined and therefore it expands 4 to the empty string with 0 at its first 3 character, or it is undefined in which case 2 it is not the empty string. This works with 1 GCC, so one can write
if( DEFINED(MACRO) ) ...
Why don't you simply define ASSERT
differently 22 depending on that macro?
#ifdef MACRO
#define ASSERT(NAME, TEST) \
do { \
printf("Assert failed"); \
} while(0)
#else
#define ASSERT(NAME, TEST) {}
#endif
Using fixed preprocessor 21 values in C conditionals should be avoided 20 - sure the compiler should optimise the 19 dead code out, but why rely on that when 18 you can essentially remove the actual C 17 code?
EDIT:
There is a rather ugly trick involving 16 macro argument stringification that you 15 might be able to use:
#include <string.h>
#include <stdio.h>
#define X
#define ERROR_(NAME, TEXT) \
if (strcmp("", #NAME) == 0) \
printf("%s\n", TEXT)
#define ERROR(n, t) ERROR_(n, t)
int main() {
ERROR(X, "Error: X");
ERROR(Y, "Error: Y");
return 0;
}
This outputs:
$ ./test
Error: X
Essentially 14 it uses the fact that when a preprocessor 13 token is not defined as a macro, it expands 12 to itself. When, on the other hand, it is defined 11 it expands to either an empty string, or 10 its definition. Unless one of your macros 9 has its own name as a definition, this hack should 8 work.
Disclaimer: Use this at your own risk!
(...because 7 I will most certainly not use it!)
EDIT 2:
The 6 assembly output of gcc -O0 -S
for the program above 5 is:
.file "test.c"
.section .rodata
.LC0:
.string "Error: X"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.4.3"
.section .note.GNU-stack,"",@progbits
Even with no optimisation, GCC reduces 4 this program to a single puts()
call. This program 3 produces exactly the same assembly output:
#include <stdio.h>
int main() {
puts("Error: X");
return 0;
}
Therefore, you 2 are probably not going to have any performance issues, depending 1 on your compiler and any optimisations...
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.