The role of #ifdef and #ifndef - c-preprocessor

#define one 0
#ifdef one
printf("one is defined ");
#ifndef one
printf("one is not defined ");
In this what is the role of #ifdef and #ifndef, and what's the output?

Text inside an ifdef/endif or ifndef/endif pair will be left in or removed by the pre-processor depending on the condition. ifdef means "if the following is defined" while ifndef means "if the following is not defined".
So:
#define one 0
#ifdef one
printf("one is defined ");
#endif
#ifndef one
printf("one is not defined ");
#endif
is equivalent to:
printf("one is defined ");
since one is defined so the ifdef is true and the ifndef is false. It doesn't matter what it's defined as. A similar (better in my opinion) piece of code to that would be:
#define one 0
#ifdef one
printf("one is defined ");
#else
printf("one is not defined ");
#endif
since that specifies the intent more clearly in this particular situation.
In your particular case, the text after the ifdef is not removed since one is defined. The text after the ifndef is removed for the same reason. There will need to be two closing endif lines at some point and the first will cause lines to start being included again, as follows:
#define one 0
+--- #ifdef one
| printf("one is defined "); // Everything in here is included.
| +- #ifndef one
| | printf("one is not defined "); // Everything in here is excluded.
| | :
| +- #endif
| : // Everything in here is included again.
+--- #endif

Someone should mention that in the question there is a little trap. #ifdef will only check if the following symbol has been defined via #define or by command line, but its value (its substitution in fact) is irrelevant. You could even write
#define one
precompilers accept that.
But if you use #if it's another thing.
#define one 0
#if one
printf("one evaluates to a truth ");
#endif
#if !one
printf("one does not evaluate to truth ");
#endif
will give one does not evaluate to truth. The keyword defined allows to get the desired behaviour.
#if defined(one)
is therefore equivalent to #ifdef
The advantage of the #if construct is to allow a better handling of code paths, try to do something like that with the old #ifdef/#ifndef pair.
#if defined(ORA_PROC) || defined(__GNUC) && __GNUC_VERSION > 300

"#if one" means that if "#define one" has been written "#if one" is executed otherwise "#ifndef one" is executed.
This is just the C Pre-Processor (CPP) Directive equivalent of the if, then, else branch statements in the C language.
i.e.
if {#define one} then printf("one evaluates to a truth ");
else
printf("one is not defined ");
so if there was no #define one statement then the else branch of the statement would be executed.

The code looks strange because the printf are not in any function blocks.

Related

error C2003: expected 'defined id'

I made a mechanism for compiling only selected tests from a sequence of tests by defining the macros:
#define SELECTION(x) ((!defined (RUN_SELECTED_TESTS_ONLY)) || (defined (x)))
#define RUN_SELECTED_TESTS_ONLY
#define TEST_1 //Lets say I want only test1 to be compiled
#if SELECTION(TEST_1) //The line I'm getting the error on.
//code of test 1
#endif
#if SELECTION(TEST_2)
//code of test 2
#endif
While compilation I'm getting the error :
error C2003: expected 'defined id'
I'm getting the error only when TEST_1 or TEST_2 (or both) are defined.
An alternative definition for SELECTION:
#ifdef RUN_SELECTED_TESTS_ONLY
#define SELECTION defined
#else
#define SELECTION(x) 1
#endif
Notes:
Must be defined after RUN_SELECTED_TESTS_ONLY is.
Only works in GNU cpp and other preprocessors similarly permissive about operator defined being the result of a macro expansion.
Example:
#define RUN_SELECTED_TESTS_ONLY
#ifdef RUN_SELECTED_TESTS_ONLY
#define SELECTION defined
#else
#define SELECTION(x) 1
#endif
#define TEST_1
//#define TEST_2
#include <stdio.h>
int main()
{
#if SELECTION(TEST_1)
printf("Test 1\n");
#endif
#if SELECTION(TEST_2)
printf("Test 2\n");
#endif
return 0;
}
Output:
Test 1
What you have invokes undefined behaviour. C standard says that the defined preprocessor operator may not appear as a result of replacement.
C11 draft, 6.10.1 Conditional inclusion
4 Prior to evaluation, macro invocations in the list of preprocessing
tokens that will become the controlling constant expression are
replaced (except for those macro names modified by the defined unary
operator), just as in normal text. If the token defined is generated
as a result of this replacement process or use of the defined unary
operator does not match one of the two specified forms prior to macro
replacement, the behavior is undefined. After all replacements due to
macro expansion and the defined unary operator have been performed,
all remaining identifiers (including those lexically identical to
keywords) are replaced with the pp-number 0, and then each
preprocessing token is converted into a token.
If you can't perform same check at run-time, you could do:
#define RUN_SELECTED_TESTS_ONLY
#define TEST_1
#if ((!defined (RUN_SELECTED_TESTS_ONLY)) || (defined (TEST_1)))
//code of test 1
#endif
Basically performing the "selection" yourself.
The error you get means: An identifier must follow the preprocessor keyword. (from MSDN).
It doesn't work because you cannot you defined() 2 times in your macro SELECTION(x).
What you can do instead is something like:
#define SELECTION(x) (!RUN_SELECTED_TESTS_ONLY || x)
#define RUN_SELECTED_TESTS_ONLY 1
#define TEST_1 1
#define TEST_2 0
#if SELECTION(TEST_1)
//some code
#endif
int main() {
printf("%d\n", SELECTION(TEST_1));
printf("%d\n", SELECTION(TEST_2));
return 0;
}

What does the c precompiler do with macros defined as (void)0

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.

#define IDENTIFIER without a token

What does the following statement mean:
#define FAHAD
I am familiar with the statements like:
#define FAHAD 1
But what does the #define statement without a token signify?
Is it that it is similar to a constant definition?
Defining a constant without a value acts as a flag to the preprocessor, and can be used like so:
#define MY_FLAG
#ifdef MY_FLAG
/* If we defined MY_FLAG, we want this to be compiled */
#else
/* We did not define MY_FLAG, we want this to be compiled instead */
#endif
it means that FAHAD is defined, you can later check if it's defined or not with:
#ifdef FAHAD
//do something
#else
//something else
#endif
Or:
#ifndef FAHAD //if not defined
//do something
#endif
A real life example use is to check if a function or a header is available for your platform, usually a build system will define macros to indicate that some functions or headers exist before actually compiling, for example this checks if signal.h is available:
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif/*HAVE_SIGNAL_H*/
This checks if some function is available
#ifdef HAVE_SOME_FUNCTION
//use this function
#else
//else use another one
#endif
Any #define results in replacing the original identifier with the replacement tokens. If there are no replacement tokens, the replacement is empty:
#define DEF_A "some stuff"
#define DEF_B 42
#define DEF_C
printf("%s is %d\n", DEF_A, DEF_B DEF_C);
expands to:
printf("%s is %d\n", "some stuff", 42 );
I put a space between 42 and ) to indicate the "nothing" that DEF_C expanded-to, but in terms of the language at least, the output of the preprocessor is merely a stream of tokens. (Actual compilers generally let you see the preprocessor output. Whether there will be any white-space here depends on the actual preprocessor. For GNU cpp, there is one.)
As in the other answers so far, you can use #ifdef to test whether an identifier has been #defined. You can also write:
#if defined(DEF_C)
for instance. These tests are positive (i.e., the identifier is defined) even if the expansion is empty.
#define FAHAD
this will act like a compiler flag, under which some code can be done.
this will instruct the compiler to compile the code present under this compiler option
#ifdef FAHAD
printf();
#else
/* NA */
#endif

Is there a way to both check a macro is defined and it equals a certain value at the same time

I regularly use object-like preprocessor macros as boolean flags in C code to turn on and off sections of code.
For example
#define DEBUG_PRINT 1
And then use it like
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
However, it comes a problem if the header file that contains the #define is forgotten to be included in the source code. Since the macro is not declared, the preprocessor treats it as if it equals 0, and the #if statement never runs.
When the header file is forgotten to be included, non-expected, unruly behaviour can occur.
Ideally, I would like to be able to both check that a macro is defined, and check that it equals a certain value, in one line. If it is not defined, the preprocessor throws an error (or warning).
I'm looking for something along the lines of:
#if-def-and-true-else-throw-error(DEBUG_PRINT)
...
#endif
It's like a combination of #ifdef and #if, and if it doesn't exist, uses #error.
I have explored a few avenues, however, preprocessor directives can't be used inside a #define block, and as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
This may not work for the general case (I don't think there's a general solution to what you're asking for), but for your specific example you might consider changing this sequence of code:
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
to:
if (DEBUG_PRINT == 1) {
printf("%s", "Testing");
}
It's no more verbose and will fail to compile if DEBUG_PRINT is not defined or if it's defined to be something that cannot be compared with 1.
as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #if statement.
It can't be an error because the C standard specifies that behavior is legal. From section 6.10.1/3 of ISO C99 standard:
After all replacements due to macro expansion and the defined unary
operator have been performed, all remaining identifiers are replaced with the pp-number
0....
As Jim Balter notes in the comment below, though, some compilers (such as gcc) can issue warnings about it. However, since the behavior of substituting 0 for unrecognized preprocessor tokens is legal (and in many cases desirable), I'd expect that enabling such warnings in practice would generate a significant amount of noise.
There's no way to do exactly what you want. If you want to generate a compilation failure if the macro is not defined, you'll have to do it explicitly
#if !defined DEBUG_PRINT
#error DEBUG_PRINT is not defined.
#endif
for each source file that cares. Alternatively, you could convert your macro to a function-like macro and avoid using #if. For example, you could define a DEBUG_PRINT macro that expands to a printf call for debug builds but expands to nothing for non-debug builds. Any file that neglects to include the header defining the macro then would fail to compile.
Edit:
Regarding desirability, I have seen numerous times where code uses:
#if ENABLE_SOME_CODE
...
#endif
instead of:
#ifdef ENABLE_SOME_CODE
...
#endif
so that #define ENABLE_SOME_CODE 0 disables the code rather than enables it.
Rather than using DEBUG_PRINT directly in your source files, put this in the header file:
#if !defined(DEBUG_PRINT)
#error DEBUG_PRINT is not defined
#endif
#if DEBUG_PRINT
#define PrintDebug([args]) [definition]
#else
#define PrintDebug
#endif
Any source file that uses PrintDebug but doesn't include the header file will fail to compile.
If you need other code than calls to PrintDebug to be compiled based on DEBUG_PRINT, consider using Michael Burr's suggestion of using plain if rather than #if (yes, the optimizer will not generate code within a false constant test).
Edit:
And you can generalize PrintDebug above to include or exclude arbitrary code as long as you don't have commas that look like macro arguments:
#if !defined(IF_DEBUG)
#error IF_DEBUG is not defined
#endif
#if IF_DEBUG
#define IfDebug(code) code
#else
#define IfDebug(code)
#endif
Then you can write stuff like
IfDebug(int count1;) // IfDebug(int count1, count2;) won't work
IfDebug(int count2;)
...
IfDebug(count1++; count2++;)
Yes you can check both:
#if defined DEBUG && DEBUG == 1
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
In this example even when #define DEBUG 0 but it is not equal to 1 thus nothing will be printed.
You can do even this:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Here if you #define DEBUG 0 and then D(1,2,3) also nothing will be printed
DOC
Simply create a macro DEBUG_PRINT that does the actual printing:
#define DEBUG_PRINT(n, str) \
\
if(n == 1) \
{ \
printf("%s", str); \
} \
else if(n == 2) \
{ \
do_something_else(); \
} \
\
#endif
#include <stdio.h>
int main()
{
DEBUG_PRINT(1, "testing");
}
If the macro isn't defined, then you will get a compiler error because the symbol is not recognized.
#if 0 // 0/1
#define DEBUG_PRINT printf("%s", "Testing")
#else
#define DEBUG_PRINT printf("%s")
#endif
So when "if 0" it'll do nothing and when "if 1" it'll execute the defined macro.

Printing name and value of a macro

I have a C program with a lot of optimizations that can be enabled or disabled with #defines. When I run my program, I would like to know what macros have been defined at compile time.
So I am trying to write a macro function to print the actual value of a macro. Something like this:
SHOW_DEFINE(X){\
if( IS_DEFINED(X) )\
printf("%s is defined and as the value %d\n", #X, (int)X);\
else\
printf("%s is not defined\n", #X);\
}
However I don't know how to make it work and I suspect it is not possible, does anyone has an idea of how to do it?
(Note that this must compile even when the macro is not defined!)
As long as you are willing to put up with the fact that SOMESTRING=SOMESTRING indicates that SOMESTRING has not been defined (view it as the token has not been redefined!?!), then the following should do:
#include <stdio.h>
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x))
#define CHARLIE -6
#define FRED 1
#define HARRY FRED
#define NORBERT ON_HOLIDAY
#define WALLY
int main()
{
SHOW_DEFINE(BERT);
SHOW_DEFINE(CHARLIE);
SHOW_DEFINE(FRED);
SHOW_DEFINE(HARRY);
SHOW_DEFINE(NORBERT);
SHOW_DEFINE(WALLY);
return 0;
}
The output is:
BERT=BERT
CHARLIE=-6
FRED=1
HARRY=1
NORBERT=ON_HOLIDAY
WALLY=
Writing a MACRO that expands to another MACRO would require the preprocessor to run twice on it.
That is not done.
You could write a simple file,
// File check-defines.c
int printCompileTimeDefines()
{
#ifdef DEF1
printf ("defined : DEF1\n");
#else // DEF1
printf ("undefined: DEF1\n");
#endif // DEF1
// and so on...
}
Use the same Compile Time define lines on this file as with the other files.
Call the function sometime at the start.
If you have the #DEFINE lines inside a source file rather than the Makefile,
Move them to another Header file and include that header across all source files,
including this check-defines.c.
Hopefully, you have the same set of defines allowed across all your source files.
Otherwise, it would be prudent to recheck the strategy of your defines.
To automate generation of this function,
you could use the M4 macro language (or even an AWK script actually).
M4 becomes your pre-pre-processor.
#ifdef MYMACRO
printf("MYMACRO defined: %d\r\n", MYMACRO);
#endif
I don't think what you are trying to do is possible. You are asking for info at runtime which has been processed before compilation. The string "MYMACRO" means nothing after CPP has expanded it to its value inside your program.
You did not specify the compiler you were using. If this is gcc, gcc -E may help you, as it stops after the preprocessing stage, and prints the preprocessing result. If you diff a gcc -E result with the original file, you may get part of what you want.
Why not simply testing it with the preprocessor ?
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
One can also embed this in another test not to print it everytime:
#if define(SHOW_DEFINE)
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
#endif
Wave library from boost can be helpful also to do what you want. If your project is big enough, I think it is worth trying. It is a C++ preprocessor, but they are the same any way :)
I believe what you are trying to do is not possible. If you are able to change the way your #defines work, then I suggest something like this:
#define ON 1
#define OFF 2
#define OPTIMIZE_FOO ON
#define OPTIMIZE_BAR OFF
#define SHOW_DEFINE(val)\
if(val == ON) printf(#val" is ON\n");\
else printf(#val" is OFF\n");
It is not possible indeed, the problem being the "not defined" part. If you'd relied on the macro values to activate/deactivate parts of your code, then you could simply do:
#define SHOW_DEFINE(X) \
do { \
if (X > 0) \
printf("%s %d\n", #X, (int)X); \
else \
printf("%s not defined\n", #X); \
} while(0)
Based on Chrisharris, answer I did this.
Though my answer is not very nice it is quite what I wanted.
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT defined")
Only bug I found is the define must not be #define XXX XXX (with XXX equals to XXX).
This question is very close from Macro which prints an expression and evaluates it (with __STRING). Chrisharris' answer is very close from the answer to the previous question.
you can use an integer variable initialized to 1.
multiply the #define with this variable and print the value of variable.

Resources