How does the following code work?
#define ENABLE_DEBUG 1
#if ENABLE_DEBUG
#define LOG_MSG printf
#else
#define LOG_MSG(...)
#endif
Depending on the value of ENABLE_DEBUG, LOG_MSG is either defined to be an alias for printf() or it is defined as a no-op macro. It is implied that you can change the value to 0 to disable debugging. This is a common technique for making it easy to switch between debugging builds which display lots of output and release builds which are quiet.
#define LOG_MSG printf
This makes it an alias for printf().
#define LOG_MSG(...) /* empty */
And this defines it as an empty macro. Notice that here it has a set of parentheses, which means the macro takes parameters. It has nothing afterwards which means it expands to absolutely nothing. And the ... indicates that this macro can take a varying number of arguments. This syntax is a C99 extension so it may not be available on older C compilers.
LOG_MSG("file not found\n");
The result is that a LOG_MSG() call will either print a message or do nothing depending on whether logging is enabled.
// If ENABLE_DEBUG is non-zero, a debugging printout:
printf("file not found\n");
// If ENABLE_DEBUG is zero, an empty statement:
;
For what it's worth, whoever authored this macro could've done a better job by replacing the first definition with one using the ... syntax (which he/she is clearly familiar with), printing to stderr instead of stdout:
#define LOG_MSG(...) fprintf(stderr, __VA_ARGS__)
This uses the preprocessor to change code before compilation.
If ENABLE_DEBUG is defined as 1, whenever the preprocessor sees
LOG_MSG("something happened");
It will replace it with
printf("something happened");
If it is defined as 0, or not defined it will replace it with nothing (as the other answer that has just been published says).
Related
I know I can use AC_CHECK_DECL / AC_CHECK_DECLS to check whether a set of headers provides a declaration for a specified identifier, but how can I check not only whether a macro is declared, but also whether its expansion meets my criteria? Specifically, I would like to check whether numa.h contains a macro definition equivalent to this ...
#define LIBNUMA_API_VERSION 2
... including the specific value "2".
UPDATE:
<numa.h> header contains a definition such as #define LIBNUMA_API_VERSION 2 to declare it's version. C code that uses this header typically uses it like so:
#if defined(LIBNUMA_API_VERSION) && LIBNUMA_API_VERSION >= 2
....
#endif
I want to determine NUMA header version with autoconf, and define a macro that succinctly conveys whether NUMA version 2 is provided. i.e.:
if test "$have_numa_v2" = "yes" ; then
AC_DEFINE(NUMA_VERSION_2, 1, [Determine whether NUMA v2 available)
fi
That could be used like so:
#ifdef NUMA_VERSION_2
....
#endif
Is it possible? I'm having trouble determining how I could set the value of variable have_numa_v2 variable in my Autoconf file.
You can use AC_COMPILE_IFELSE or AC_RUN_IFELSE with a suitably-structured test program to determine whether the macro is defined to a specific value you designate. For example, supposing that the current language is C:
have_numa_v2=no
AC_RUN_IFELSE([AC_LANG_PROGRAM([
#include <numa.h>
],[
#if LIBNUMA_API_VERSION != 2
exit(1);
#endif
])], [have_numa_v2=yes])
That constructs a program whose return value depends on whether LIBNUMA_API_VERSION is defined as a macro, and if so, whether it expands to 2. If Autoconf cannot compile it (because, say, it cannot find numa.h) or if it exits with a status other than 0 then nothing else happens ($have_numa_v2 retains its assigned value of "no"). Otherwise, the assignment in the second argument is performed, and $have_numa_v2 ends up with the value "yes".
For what it's worth, the source of the particular test program produced and used by that macro contains some Autoconf-standard macro definitions, plus this:
#include <numa.h>
int
main ()
{
#if LIBNUMA_API_VERSION != 2
exit(1);
#endif
;
return 0;
}
The version using AC_COMPILE_IFELSE would be similar, but built around using an #error preprocessor directive to make compilation fail if the macro is not defined to the specified value. That variation might be a better choice if you anticipate any possibility that your program will be cross-compiled for a foreign architecture.
I find it difficult to understand the working of a macro defined with the help of preprocessor directives.
The macro,
TRXEM_SPI_BEGIN()
is defined with the help of two preprocessor directives refereed from two header files. Firstly, I wish to state the declaration of the said macro.
#define TRXEM_SPI_BEGIN() st( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP();)
As the declaration of macro st () is missing here, I found it defined in a different header file and ti is shown below.
#define st(x) do { x } while (__LINE__ == -1)
Now after combining two macros, the true definition of macro TRXEM_SPI_BEGIN() must be,
#define TRXEM_SPI_BEGIN() do {
( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; NOP(); )
} while (__LINE__ == -1)
This code is written to work inside a microcontroler where TRXEM_PORT_OUT, RXEM_SPI_SC_N_PIN are memory mapped registers and NOP initiates an instruction cycle that does nothing.
As per my understanding, __LINE__ means the line of code in the c file where __LINE__ lies. That line can never be equal to -1. i.e. this loopmust always be running only once provided the __LINE__ can never be placed in -1 place in a .c file. Simply put, -1 can never be the value of __LINE__.
Therefore, I believe a do while() loop here is unnecessary and the same output could have been achieved by simply without using any looping.
I do not understand the functioning of this macro. I would so much appreciate if someone could elaborate on it.
As per my understanding, means the line of code in the c file
where __LINE__ lies. That line can never be equal to -1. i.e. this
loopmust always be running only once provided the __LINE__ can never
be placed in -1 place in a .c file. Simply put, -1 can never be the
return value to a __LINE__.
Your understanding is exactly correct here. It is there to make sure the code runs exactly once.
Think of following scenario:
#define BAZ foo();bar();
Now if you do
if(some_cond) BAZ;
This is equivalent to:
if(some_cond) foo();
bar();
Which is most possibly not something you want. So you change it to:
#define BAZ {foo();bar();}
This works fine if written as if(some_cond) foo() else wow(); but would fail compilation if written as if(some_cond) foo(); else wow();
So you define BAZ as
/* No semicolon at end */
#define BAZ do {foo();bar();} while(condition_which_is_always_false)
And you can now write the natural code with intuitive semicolon at end.
In your case, condition_which_is_always_false is __LINE__ == -1
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.
What MACRO can be used to switch off printf statements, rather than removing them all for deployment builds, I just want to switch them off, skip them, ignore them.
EDIT: I personally use gcc, but code is part of a larger project which will be compiled on a Panda board running Ubuntu.
Not exactly what you ask for, but I use this construct in my code for debug output when I do not have a proper logging system handy:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
So I can do this all over my code
SPAM(("foo: %d\n", 42));
and then disable all of them by changing 1 to 0 in #if above.
But if you have variadic macro support in all compilers that you write code for, then you may go for other answers and just redefine printf. (That being said, I find it useful to distinct debugging prints from regular ones in code — using a different function name helps readability.)
Note that you also can redirect stdout to the /dev/null, but I assume that you want to get rid from runtime overhead as well.
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
See also C #define macro for debug printing which discusses some important issues closely related to this.
Two options, either:
#define printf(...)
(requires C99 variadic macro parameters), you need to put it in some common header file which is never included before stdio.h, if there is one..
Or you can tell the linker to link it to something else, in GCC you would define
int wrap_printf(void) {return 0;}
and link using
--wrap printf
All that said, you should probably not be using printf for printing debug output, but rather a macro or utility function (which in turn can use printf if you'd like) which you have better control over.
Hope that helps.
If you want to avoid the potential warning that Jonathan's answer may give you and if you don't mind an empty call to printf you could also do something like
#define printf(...) printf("")
This works because C macros are not recursive. The expanded printf("") will just be left as such.
Another variant (since you are using gcc) would be something like
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
and in one compilation unit
int ignore_printf(char const*, ...)
I use to prefix the debug printf()s (not all of them) with PDEB.
For the debug builds, I compile with -DPDEB= (nothing)
For the release builds, I compile with -DPDEB="0&&" or -DPDEB="0 && "
That way, the following code (test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
outputs:
either (in release mode):
normal print
either (in debug mode):
normal print
debug print
Ideally, one could aim for turning the PDEB into the "//" (comments mark), except that this is not possible under the standard pre-/processing chain.
Another possibility would be something like freopen("/dev/null", "w", stdout);
This doesn't exactly disable printf though -- it's roughly equivalent to running your program with stdout redirected to /dev/null, like: ./myprog > /dev/null at the shell prompt.
I included #define printf // in common header file. It will suppress all the printf.
Below simple function serves the purpose, I use the same.
int printf(const char *fmt, ...)
{
return (0)
}
Use this macro to enable or disable the printf.
//Uncomment the following line to enable the printf function.
//#define ENABLE_PRINTF
#ifdef ENABLE_PRINTF
#define DEBUG_PRINTF(f,...) printf(f,##__VA_ARGS__)
#else
#define DEBUG_PRINTF(f,...)
#endif
Then call "DEBUG_PRINTF" instead of "printf".
For example:
DEBUG_PRINTF("Hello world: %d", whateverCount);
I have used two macros for this. The first one defines the condition to print. In this simple example we print any time the parameter is not zero. More complex expressions can be used.
The second one determines, based on the first macro, to call or not printf.
If the condition can be determined by the compiler (with the right optimization settings) no code is generated.
If the condition cannot be determined at compile time then will be at run time. One of the advantages of this method is that if printf is not going to happen then the whole printf is not evaluated avoiding many conversions to string that can happen in a complex printf statement.
#define need_to_print(flag) ((flag) != 0))
#define my_printf(debug_level, ...) \
({ \
if(need_to_print(debug_level)) \
printf(__VA_ARGS__); \
})
to use it call my_printf instead of printf and add a parameter at the beginning for the print condition.
my_printf(0, "value = %d\n", vv); //this will not print
my_printf(1, "value = %d\n", vv); //this will print
my_printf(print_debug, "value = %d\n", vv); //this will print if print_debug != 0
the ( ... ) parenthesis surrounding the macro make it a single statement.
In C/C++
What happens to code placed between an #if 0/#endif block?
#if 0
//Code goes here
#endif
Does the code simply get skipped and therefore does not get executed?
Not only does it not get executed, it doesn't even get compiled.
#if is a preprocessor command, which gets evaluated before the actual compilation step. The code inside that block doesn't appear in the compiled binary.
It's often used for temporarily removing segments of code with the intention of turning them back on later.
It's identical to commenting out the block, except with one important difference: Nesting is not a problem. Consider this code:
foo();
bar(x, y); /* x must not be NULL */
baz();
If I want to comment it out, I might try:
/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/
Bzzt. Syntax error! Why? Because block comments do not nest, and so (as you can see from SO's syntax highlighting) the */ after the word "NULL" terminates the comment, making the baz call not commented out, and the */ after baz a syntax error. On the other hand:
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
Works to comment out the entire thing. And the #if 0s will nest with each other, like so:
#if 0
pre_foo();
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
quux();
#endif
Although of course this can get a bit confusing and become a maintenance headache if not commented properly.
It permanently comments out that code so the compiler will never compile it.
The coder can later change the #ifdef to have that code compile in the program if he wants to.
It's exactly like the code doesn't exist.
I'd like to add on for the #else case:
#if 0
/* Code here will NOT be complied. */
#else
/* Code will be compiled. */
#endif
#if 1
/* Code will be complied. */
#else
/* Code will NOT be compiled. */
#endif
When the preprocessor sees #if it checks whether the next token has a non-zero value. If it does, it keeps the code around for the compiler. If it doesn't, it gets rid of that code so the compiler never sees it.
If someone says #if 0 they are effectively commenting out the code so it will never be compiled. You can think of this the same as if they had put /* ... */ around it. It's not quite the same, but it has the same effect.
If you want to understand what happened in detail, you can often look. Many compilers will allow you to see the files after the preprocessor has run. For example, on Visual C++ the switch /P command will execute the preprocessor and put the results in a .i file.
Lines beginning with a # are preprocessor directives. #if 0 [...] #endif blocks do not make it to the compiler and will generate no machine code.
You can demonstrate what happens with the preprocessor with a source file ifdef.cxx:
#if 0
This code will not be compiled
#else
int i = 0;
#endif
Running gcc -E ifdef.cxx will show you what gets compiled.
You may choose to use this mechanism to prevent a block of code being compiled during the development cycle, but you would probably not want to check it in to your source control as it just adds cruft to your code and reduces readability. If it's a historical piece of code that has been commented out, then it should be removed: source control contains the history, right?
Also, the answer may be the same for both C and C++ but there is no language called C/C++ and it's not a good habit to refer to such a language.
Not quite
int main(void)
{
#if 0
the apostrophe ' causes a warning
#endif
return 0;
}
It shows "t.c:4:19: warning: missing terminating ' character"
with gcc 4.2.4
It is a cheap way to comment out, but I suspect that it could have debugging potential. For example, let's suppose you have a build that output values to a file. You might not want that in a final version so you can use the #if 0... #endif.
Also, I suspect a better way of doing it for debug purpose would be to do:
#ifdef DEBUG
// output to file
#endif
You can do something like that and it might make more sense and all you have to do is define DEBUG to see the results.