Put it simply, in my C++ knowledge (or lack of) FOO will be substituted with what is in parenthesis when this was defined. But what happens if the parenthesis are empty? Is it equivalent to 0? That means a #ifdef foo (0) will do the same thing as #ifdef foo ( )? If equivalent is any useful effect to be used with empty parentheses?
A macro expansion will just expand to whatever the macro is expanded to:
#include <stdio.h>
#define L (
#define R )
#define l {
#define r }
#define LR ()
int main LR
l
printf L "Hello, World\n" R;
return 0;
r
would compile perfectly fine (and if you hid the L/R/l/r macros in a header file, nobody would understand what you'd done. Note that spaces are needed at least in some places to ensure the macro actually expands.
This statement
#ifdef CRAPFOO ()
won't compile cleanly ("extra tokens at the end of #ifdef" in gcc, other compilers may give other errors.
#define CRAPFOO ()
#ifdef CRAPFOO
do something
#else
not something
#endif
will give do something as the result.
#define is an absolutely dumb textual replacement. So:
#define FOO ()
int main()
{
FOO;
}
becomes
int main()
{
();
}
You can test this with the -E option to g++ (and I think clang too), which means "just do preprocessing", or equivalently, just run the cpp tool, which is the c preprocessor.
i.e.
$ echo -e "#define FOO ()\nint main()\n{\n FOO;\n}" > def.cpp ; g++ -E def.cpp
# 1 "def.cpp"
# 1 "<command-line>"
# 1 "def.cpp"
int main()
{
();
}
(These are the Linux/other Unix command line tools).
#define is a preprocessor directive and is just a stupid text replacement rule which happens before actually compiling your code. There's no code model yet when applying the macro definitions.
#define FOO ()
replaces every occurrence of FOO with ().
#define FOO (0)
replaces every occurrence of FOO with (0).
#define FOO 0
replaces every occurrence of FOO with 0, which is not the same as (0) (there are cases in which this makes a difference).
However,
#define FOO()
replaces FOO() with nothing, doesn't touch FOO
Related
I have several configuration files each one containing the definition of some boolean macro, to be set to 0 or 1. Then, in my code, I check the value of such a macro to decide which part of the code to activate. Now comes the tricky part: I want to be sure that the header containing the definition of my macro has been included.
In the following example, if I forget to include the header file containing FOO definition, the compiler will print "world!", while I would like instead that it generated an error.
//in the configuration header file
#define FOO 1
//in a cpp file
#if FOO //I would like this to generate an error if I forgot to include the header file
#pragma message "Hello"
#else
#pragma message "world!"
#endif
Is it possible to achieve such a behaviour? How?
To clarify, I am not asking how to generate an error if a macro is not defined, but if it is possible to transform the #if FOO line so that, at the same time, it checks the boolean value and generates an error if FOO is not defined.
The point of having this would be that developers would know that their code should contain
SPECIAL_MACRO(FOO)
which, at the same time, check the boolean value of FOO as if it was an #if FOO statement, and prevents them from forgetting the inclusion of the header defining FOO.
Colleagues (hi Hartmut, Kurt) who maintained a large code base which was extensively configured with #defines ran exactly into the same problem. A simple mis-spelling, possibly in a make file, could result in subtle errors which were hard to track down. Their solution: Use function macros! In
#if SOME_COND()
// ...
#endif
the compiler complains if SOME_COND() is not defined, as opposed to a simple SOME_COND which will be replaced by 0 if undefined. I like it because it can be used to transport several values without cluttering the code up with additional #ifdefs.
The accepted answer of using function-macros is good, but if you want to keep normal macros - and still use the value of FOO if defined and generate an error otherwise you could do:
#if FOO / defined(FOO)
#else
#endif
If FOO is not defined it will trigger integer division by zero.
What about using the -Wundef gcc preprocessor option? This will only generate a warning, which can easily be turned to an error with -Werror=undef.
Macro CHECK(x) will:
fail if macro x is undefined,
evaluate to 00 if x is defined to 0
evaluate to 01 if x is defined to 1
$ cat main.cpp
#define CAT(x, y) x##y
#define CHECK(x) CAT(0, x)
// usage
#define COND0 0
#define COND1 1
#if CHECK(COND)
#endif
#if CHECK(COND0)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
#if CHECK(COND1)
#pragma message "defined 1"
#else
#pragma message "defined 0"
#endif
$ g++ main.cpp
main.cpp:9:1: error: user-defined literal in preprocessor expression
9 | #if CHECK(COND)
| ^~~~~
main.cpp:15:17: note: ‘#pragma message: defined 0’
15 | #pragma message "defined 0"
| ^~~~~~~~~~~
main.cpp:19:17: note: ‘#pragma message: defined 1’
19 | #pragma message "defined 1"
| ^~~~~~~~~~~
I think can solve your problem in simple tricky solution. I change your code as below and my code understand that header.h doesn't exist and show error to me.
#if FOO == 1
#pragma message "Hello"
#elif FOO == 2
#pragma message "world!"
#else
throw std::invalid_argument("Header didn't add to project");
#endif
only you need to change your initial value for Foo.
because compiler activate Foo==0 when it doesn't find FOO, you shouldn't use 0 value for your configuration. you should leave zero for header absence situation.instead you must use values greater than zero(1 , 2, 3 , ...).
Foo==0 absence situation.
Foo==1 Configuration 1.
Foo==2 Configuration 2.
.
.
.
Is it possible to disable chunks of code with c/c++ preprocessor depending on some definition, without instrumenting code with #ifdef #endif?
// if ENABLE_TEST_SONAR is not defined, test code will be eliminated by preprocessor
TEST_BEGIN(SONAR)
uint8_t sonar_range = get_sonar_measurement(i);
TEST_ASSERT(sonar_range < 300)
TEST_ASSERT(sonar_range > 100)
TEST_END
Functionally equivalent to something as follows:
#ifdef TEST_SONAR
serial_print("test_case sonar:\r\n");
uint8_t sonar_range = get_sonar_measurement(i);
serial_print(" test sonar_range < 300:%d\r\n", sonar_range < 300);
serial_print(" test sonar_range > 100:%d\r\n", sonar_range > 100);
#endif TEST_SONAR
Multiple lines can be disabled only with #ifdef or #if but single lines can be disabled with a macro. Note that multiple lines can be combined with \
#ifdef DOIT
#define MYMACRO(x) \
some code \
more code \
even more \
#else
#define MYMACRO(x)
#endif
Then when you call MYMACRO anplace that code will either be included or not based on whether DOIT is defined
That's the closest you can come and is used frequently for debugging code
EDIT: On a whim I tried the following and it seems to work (in MSVC++ and g++):
#define DOIT
#ifdef DOIT
#define MYMACRO(x) x
#else
#define MYMACRO(x)
#endif
void foo(int, int, int)
{
}
int main(int, char **)
{
int x = 7;
MYMACRO(
if (x)
return 27;
for (int i = 0; i < 10; ++i)
foo(1, 2, 3);
)
}
No, the only way to disable sections of codes effectively using preprocessing is by #ifdef #endif. Theoretically, you could use #if identifier, but it's better to stick to checking whether a variable is defined.
Another option (perhaps) is to use a preprocessing macro:
Edit:
Perhaps using plain functions and #ifdef might work better?
function test_function() {
/* Do whatever test */
}
#define TESTING_IDENTIFIER
#define TEST( i, f ) if ((i)) do { f } while (0)
Then, for each test, you define a unique identifier and call it by providing the identifier first and the function (with parenthesis) second.
TEST( TESTING_IDENTIFIER, test_function() );
Finally, f can be anything that's syntactically correct -- You don't have to create a function for every test, you can put the code inline.
I will anyway mention an obvious solution of
#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
...
TEST_SONAR
code
TEST_SONAR_END
The code will still get compiled, not completely removed, but some smart compilers might optimize it out.
UPD: just tested and
#include <iostream>
using namespace std;
//#define DO_TEST_SONAR
#ifdef DO_TEST_SONAR
#define TEST_SONAR if(true) {
#else
#define TEST_SONAR if(false) {
#endif
#define TEST_SONAR_END }
int main() {
TEST_SONAR
cout << "abc" << endl;
TEST_SONAR_END
}
produces absolutely identical binaries with cout line commented out and non commented, so indeed the code is stripped. Using g++ 4.9.2 with -O2.
Could someone please explain why this works:
#include <iostream>
using namespace std;
#define cat(a,b) cat_1(a,b)
#define cat_1(a,b) a ## b
int main()
{
cat(c,cat(o,cat(u,t))) << "Hello world!";
return 0;
}
but the same code with one less level of macro indirection does not:
#include <iostream>
using namespace std;
#define cat(a,b) a ## b
int main()
{
cat(c,cat(o,cat(u,t))) << "Hello world!";
return 0;
}
I've looked at this:
http://www.boost.org/doc/libs/1_55_0/libs/preprocessor/doc/
but while it illustrates the problem I still don't understand how this solves it. When I run the preprocessor on this (g++ -E):
#include <iostream>
using namespace std;
#define cat(a,b) cat_1(a,b)
int main()
{
cat(c,cat(o,cat(u,t))) << "Hello world!";
return 0;
}
it expands the line to:
cat_1(c,cat_1(o,cat_1(u,t))) << "Hello world!"
so it looks like the problem should still be there since it maps directly to the line with just 'cat'
## operator is applied before the macro substitution is re-scanned for more macro invocations. The outer invocation first expands to ccat(o,cat(u,t)), then to ccat(o, ut) and stops there.
Extra indirection allows re-scanning to work before token pasting.
Short answer: the presence of an ## operator in a macro definition stops the normal cascading substitution of macro parameters near it.
Take a subset of the first (working) version:
#define cat(a,b) cat_1(a,b)
#define cat_1(a,b) a ## b
cat(o,cat(u,t))
The last line is tokenised:
cat ( o , cat ( u , t ) )
The cat and ( tokens indicate the start of a call to the cat() macro, so the preprocessor starts replacing it with the definition of cat():
cat_1(
at this point it has to replace "a" with the argument passed in (ie. "o"), so it continues:
cat_1(o,
now it has to replace the parameter "b" with the argument passed in (ie. "cat(u,t))"), but this argument is itself a macro call, so that gets expanded before substitution to "cat_1(u,t)" and then to "u ## t" and finally to "ut", so, getting back to the top level, we end up with:
cat_1(o,ut)
which is the re-scanned, turning into:
o ## ut
and finally to
out
as expected.
In the non-working case, the rule about non-expansion near the ## comes into play:
#define cat(a,b) a ## b
cat(o,cat(u,t))
This time when the preprocessor starts replacing the outer cat() call, it immediately encounters the parameter "a" and has to replace it with the passed argument "o", which is fine, following by the ##:
o ##
Now it gets to "b" which it must replace with the argument "cat(u,t)". However, unlike the working example above, this time, the argument isn't recursively expanded because, according to the C Standard, parameters immediately preceding or following a ## operator must not be recursively expanded. So, it just leaves the "cat(u,t)" as it got it and ends up with:
o ## cat(u,t)
which is then collapsed into
ocat(u,t)
which is where the preprocessor stops, since it doesn't know about "ocat".
The ## (and #) preprocessor operators stopping recursive parameter expansion is set out in section 6.10.3.1 of the C Standard.
#include <iostream>
#define help(a) #a
#define xhelp(a) help(a)
#define glue(a,b) a##b
#define xglue(a,b) glue(a,b)
#define HIGHLOW "hello"
#define LOWLOW ",world"
int main()
{
std::cout<<xhelp(xglue(HIGH,LOW))<<std::endl;
return 0;
}
here is my test code. I want to know the spread of the MACOR xglue(HIGH,LOW).
For me, i think the result is "hello"
but i learn from one website, the result is "hello, world".
I am really confused with it.
the result of my code is aslo "hello".
Is there anyone could help me with it?
I think the xgule(HIGH,LOW)=glue(HIGH,LOW)=HIGHLOW="hello"
THe website show that xglue(HIGH,LOW)=glue(HIGH,LOW",world")="hello, world"
First of all, there is no recursive macro.
Most work in the example is performed by the two preprocessor operators # and ##.
# is a unary operator that turns its argument into a string literal.
## is a binary operator that pastes two tokens together to form one single token.
The easiest way to check what a given preprocessor code expands to is actually to run the preprocessor. The g++ compiler has a -E option to do exactly that.
# Assuming your file is saved as code.cpp
$ g++ -E code.cpp
... lots of output ...
int main()
{
std::cout<<"\"hello\""<<std::endl;
return 0;
}
Is it possible to do something like this
#ifdef SOMETHING
#define foo //
#else
#define foo MyFunction
#endif
The idea is that if SOMETHING is defined, then calls to foo(...) become comments (or something that doesn't get evaluated or compiled), otherwise it becomes a call to MyFunction.
I've seen __noop used, but I don't believe I can use that.
EDIT(s):
I don't think I can really use a macro here, because MyFunction takes a variable number of arguments.
Also, I'd like to make it so the arguments are NOT evaluated! (So doing something like commenting out the body of MyFunction doesn't really give me what I need, as the arguments will still be evaluated)
Try this:
#ifdef SOMETHING
#define foo(x)
#else
#define foo(x) MyFunction(x)
#endif
If your function has several arguments, then:
#ifdef SOMETHING
#define foo(x,y,z)
#else
#define foo(x,y,z) MyFunction(x,y,z)
#endif
If your function has a variable number of arguments, then your compiler may support so-called "variadic macros", like this:
#ifdef SOMETHING
#define foo(...)
#else
#define foo(...) MyFunction(__VA_ARGS__)
#endif
The reason which I've seen this kind of thing used in practice is to get rid of logging functions from a release build. However, see also Separate 'debug' and 'release' builds? in which people question whether you should even have different builds.
Alternatively, instead of redefining the function call as nothing, Jonathan's comment to this answer suggested doing something like the following:
#ifdef SOMETHING
#define foo(...) do { if (false) MyFunction(__VA_ARGS__) } while (0)
#else
#define foo(...) do { if (true) MyFunction(__VA_ARGS__) } while (0)
#endif
The reasoning for doing this is so that the function call is always compiled (so it won't be left with gratuitous errors like references to deleted variables), but only called when needed: see Kernighan & Pike The Practice of Programming and also the Goddard Space Flight Center programming standards.
From a debug.h file (originating from 1990, and therefore not using __VA_ARGS__):
/*
** Usage: TRACE((level, fmt, ...))
** "level" is the debugging level which must be operational for the output
** to appear. "fmt" is a printf format string. "..." is whatever extra
** arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike.
*/
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x) do { if (0) db_print x; } while (0)
#endif /* DEBUG */
With C99, there's no longer a need for the double parentheses trick. New code should not use it unless C89 compatibility is an issue.
Maybe an easier way to do this would be to conditionally omit the body of the function?
void MyFunction() {
#ifndef SOMETHING
<body of function>
#endif
}
Unless you specifically don't want a function call to be made at all, this seems like a clean way to achieve your goal.
Unfortunately the current C++ version doesn't support variadic macros.
However, you can do this:
#ifdef SOMETHING
#define foo
#else
#define foo(args) MyFunction args
#endif
// you call it with double parens:
foo((a, b, c));
If, in the case you don't want foo called, you define it as:
void foo() {}
any calls to foo() should be optimized way.
What about something along these lines:
#ifdef NDEBUG
#define DEBUG(STATEMENT) ((void)0)
#else
#define DEBUG(STATEMENT) (STATEMENT)
#endif
You would use it like this to log debugging messages:
DEBUG(puts("compile with -DNDEBUG and I'm gone"));
A non-generic version for formatted output with additional debugging information using C99 variadic macros and the __func__ identifier could look like this:
#ifdef NDEBUG
#define Dprintf(FORMAT, ...) ((void)0)
#define Dputs(MSG) ((void)0)
#else
#define Dprintf(FORMAT, ...) \
fprintf(stderr, "%s() in %s, line %i: " FORMAT "\n", \
__func__, __FILE__, __LINE__, __VA_ARGS__)
#define Dputs(MSG) Dprintf("%s", MSG)
#endif
Here's how you'd use these macros:
Dprintf("count = %i", count);
Dputs("checkpoint passed");
Likely, you don't want to do the simple "code removal" as suggested,
because your callers will be expecting the side effects of the
arguments to happen. Here are some troublesome caller snippets that
should get you thinking:
// pre/post increment inside method call:
MyFunction(i++);
// Function call (with side effects) used as method argument:
MyFunction( StoreNewUsernameIntoDatabase(username) );
If you were to disable MyFunction by simply saying:
#define MyFunction(x)
then the side effects that the callers were expecting would go away,
and their code would break, and be quite difficult to debug. I like
the "sizeof" suggestion above, and I also like the suggestion to just
disable the body of MyFunction() via #ifdef's, although that means
that all callers get the same version of MyFunction(). From your
problem statement, I presume that's not actually what you want.
If you really need to disable MyFunction() via preprocessor defines on
a per-source-file basis, then I'd do it like this:
#ifdef SOMETHING
#define MyFunction(x) NoOp_MyFunction(x)
int NoOp_MyFunction(x) { }
#endif
You could even include the implementation of NoOp_MyFunction() inside
the source & headers for MyFunction(). You also have the flexibility
to add extra logging or debugging information in NoOp_MyFunction() as
well.
No, the C and C++ Standards say you cannot #define something to be a comment, so
#define foo //
won't work.
#ifdef SOMETHING
#define foo sizeof
#else
#define foo MyFunction
#endif
I'm assuming that foo is a printf style function? Anyways, this won't work with a zero parameter function, but if that were the case, you would already know what to do. If you really want to be anal you can use (void)sizeof but that's probably unnecessary.
I'm a little reluctant to post this answer because it's use of macro hackery can become the source of problems. However - if the calls to the function you want to have disappear are always used alone in a statement (ie., they are never part of a larger expression), then something like the following could work (and it handles varargs):
#ifdef SOMETHING
#define foo (1) ? ((void) 0) : (void)
#else
#define foo MyFunction
#endif
So if you have the line of code:
foo( "this is a %s - a++ is %d\n", "test", a++);
it will end up after the preprocessing step as either:
MyFunction( "this is a %s - a++ is %d\n", "test", a++);
or
(1) ? ((void) 0) : (void)( "this is a %s - a++ is %d\n", "test", a++);
which turns the pseudo-function's parameter list into a bunch of expressions separated by the comma operator that will never be evaluated, since the conditional always returns the ((void) 0) result.
A variant of this is something close to what ChriSW and Jonathan Leffler suggested:
#ifdef SOMETHING
#define foo if (0) MyFunction
#else
#define foo if (1) MyFunction
#endif
This is slightly different in that it does not require the compiler to support variadic macros (__VA_ARGS__).
I think this can be useful for eliminating debug trace function calls which are generally never combined into a larger expression, but beyond that I think it's a dangerous technique.
Note the potential for problems - especially if the parameters in the call produce side-effects (this is a general problem with macros - not just this hack). In the example, the a++ will be evaluated only if SOMETHING is defined in the build, otherwise it's not. So if code after the call depends on the value of a to be incremented, one of the builds has a bug.
If I remember correctly, you should be able to #define your macro to "nothing" and that will cause the compiler to ignore that call
#define foo()
foo(); // this will be ignored
What about surrounding each call to myFunction with
#ifdef SOMETHING
myFunction(...);
#endif
?