I use a macro in C++ to switch between compiling logging or not:
#define MAYBE_LOG(msg)
#ifdef PRINT_MSGS
ALWAYS_LOG(msg)
#endif
How does the #define know where the ending is? The #endif refers to the #ifdef, not the #define.
#define ends at end of the line (which might be extended with final \)
The code in the question does two separate things: it defines a macro named MAYBE_LOG with no body and, if PRINT_MSGS is defined, it uses a macro named ALWAYS_LOG. If that's not what it's supposed to do, then, yes, it needs to be changed. Since the question doesn't say what the code is supposed to do, this is just a guess:
#ifdef PRINT_MSGS
#define MAYBE_LOG(msg) ALWAYS_LOG(msg)
#else
#define MAYBE_LOG(msg)
#endif
The reason for doing it this way (and not using \ on each line to extend the macro definition is that you can't put #if conditions inside the definition of a macro.
Related
Imagine I have some "assert like" functionality, which declares a macro one way if a specific macro is defined, and a different way if it is not:
// in some header assert2.hpp
#ifdef NO_ASSERT2
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here, the NO_ASSERT2 macro is very much like the NDEBUG macro in standard assert(3).
What I'd like to do, however is allow the user to override the NO_ASSERT2 check with their own macro, before including the file. E.g., if you included assert2.hpp like this:
#define NO_ASSERT_KEY NO_ASSERT_CUSTOM
#include "assert2.hpp"
Then the macro NO_ASSERT_CUSTOM would be checked instead of the default NO_ASSERT2 for this translation unit.
It doesn't have to work exactly like the above - I just need some way to override the behavior on a per-file basis, without needing more than the 1 line of boilerplate shown above at the location of the include.
This isn't pretty... but this approach may work for you. It assumes that the macro is defined using either #define FOO, #define FOO 1, or -DFOO (assuming as typical that this creates something equivalent to #define FOO 1).
#define SECOND(...) SECOND_I(__VA_ARGS__,,)
#define SECOND_I(A,B,...) B
#define GLUE3(A,B,C) GLUE3_I(A,B,C)
#define GLUE3_I(A,B,C) A##B##C
#define AGLUE3(A,B,C) AGLUE3_I(A,B,C)
#define AGLUE3_I(A,B,C) A##B##C
#define TEST_ASSERT_KEY GLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT_KEY)
#define NO_ASSERT_PROBE0_NO_ASSERT_KEY AGLUE3(NO_ASSERT_PROBE,0_,NO_ASSERT2)
#define NO_ASSERT_PROBE0_ ,1
#define NO_ASSERT_PROBE0_1 ,1
#define NO_ASSERT_TEST SECOND(TEST_ASSERT_KEY,0)
With this, your usage would be:
#if NO_ASSERT_TEST
#define assert2(x)
#else
#define assert2(x) assert2_handler(x);
#endif
Here's a demo at stacked-crooked.
This uses pattern matching in the preprocessor via the indirect SECOND macro. The idea is that it expands to its second argument, but only indirectly... this allows you to construct as the first argument a pattern. Usually that first argument's ignored, but if you want to match something you can set it up to where the first argument would be a macro that expands with a comma; that shifts a new second argument in, replacing the default.
From here it's easier to explain backwards. NO_ASSERT_TEST uses TEST_ASSERT_KEY to construct a pattern with a default of 0. TEST_ASSERT_KEY builds NO_ASSERT_PROBE0_ concatenated with NO_ASSERT_KEY. When NO_ASSERT_KEY is defined, this would build NO_ASSERT_PROBE0_ concatenated with the expansion of what it's defined as. Otherwise it rebuilds the test token using NO_ASSERT_PROBE0_ concatenated with NO_ASSERT2.
Either way this is an indirect paste, so NO_ASSERT_KEY in the former case or NO_ASSERT2 in the latter is expanded first. In the former case, if say NO_ASSERT_KEY is NO_ASSERT_CUSTOM and NO_ASSERT_CUSTOM is not defined, this builds NO_ASSERT_PROBE0_NO_ASSERT_CUSTOM, which is just a normal identifier, which will be ignored, which results in 0 due to the SECOND in NO_ASSERT_TEST. But if NO_ASSERT_CUSTOM is defined per #define NO_ASSERT_CUSTOM, this produces NO_ASSERT_PROBE0_, which expands to ,1, which shifts 1 into the SECOND call in NO_ASSERT_TEST. Likewise if NO_ASSERT_CUSTOM is defined per -DNO_ASSERT_CUSTOM on the command line, that would (typically) make its definition equivalent to #define NO_ASSERT_CUSTOM 1, which would produce NO_ASSERT_PROBE0_1, which expands to ,1.
The cases for when NO_ASSERT_KEY is not defined are similar.
There's probably a prettier way to build this construct, if anyone wants to take a shot.
typically #define would be used to define a constant or a macro. However it is valid code to use #define in the following way.
#define MAX // does this do anything?
#define MAX 10 // I know how to treat this.
So, if I #define MAX 10, I know my pre-processor replaces all instances of MAX with 10. If someone uses #define MAX by itself however with no following replacement value, it's valid. Does this actually DO anything?
My reason for asking is that I am writing a compiler for c in c++ and handling preprocessor directives is required but I haven't been able to find out if there is any functionality I need to have when this occurs or if I just ignore this once my preprocess is done.
My first instinct is that this will create a symbol in my symbol table with no value named MAX, but it is equally possible it will do nothing.
As an add in question which is kind of bad form I know, but I'm really curious. Are there situations in real code where something like this would be used?
Thanks,
Binx
A typical example are header guards:
#ifndef MYHEADER
#define MYHEADER
...
#endif
You can test if something is defined with #ifdef / ifndef.
It creates a symbol with a blank definition, which can later be used in other preprocessor operations. There are a few things it can be used for:
1) Branching.
Consider the following:
#define ARBITRARY_SYMBOL
// ...
#ifdef ARBITRARY_SYMBOL
someCode();
#else /* ARBITRARY_SYMBOL */
someOtherCode();
#endif /* ARBITRARY_SYMBOL */
The existence of a symbol can be used to branch, selectively choosing the proper code for the situation. A good use of this is handling platform-specific equivalent code:
#if defined(_WIN32) || defined(_WIN64)
windowsCode();
#elif defined(__unix__)
unixCode();
#endif /* platform branching */
This can also be used to dummy code out, based on the situation. For example, if you want to have a function that only exists while debugging, you might have something like this:
#ifdef DEBUG
return_type function(parameter_list) {
function_body;
}
#endif /* DEBUG */
1A) Header guards.
Building on the above, header guards are a means of dummying out an entire header if it's already included in a project that spans multiple source files.
#ifndef HEADER_GUARD
#define HEADER_GUARD
// Header...
#endif /* HEADER_GUARD */
2) Dummying out a symbol.
You can also use defines with blank definitions to dummy out a symbol, when combined with branching. Consider the following:
#ifdef _WIN32
#define STDCALL __stdcall
#define CDECL __cdecl
// etc.
#elif defined(__unix__)
#define STDCALL
#define CDECL
#endif /* platform-specific */
// ...
void CDECL cdeclFunc(int, int, char, const std::string&, bool);
// Compiles as void __cdecl cdeclFunc(/* args */) on Windows.
// Compiles as void cdeclFunc(/* args */) on *nix.
Doing something like this allows you to write platform-independent code, but with the ability to specify the calling convention on Windows platforms. [Note that the header windef.h does this, defining CDECL, PASCAL, and WINAPI as blank symbols on platforms that don't support them.] This can also be used in other situations, whenever you need a preprocessor symbol to only expand to something else under certain conditions.
3) Documentation.
Blank macros can also be used to document code, since the preprocessor can strip them out. Microsoft is fond of this approach, using it in windef.h for the IN and OUT symbols often seen in Windows function prototypes.
There are likely other uses as well, but those are the only ones I can think of off the top of my head.
It doesn't "do" anything in the sense that it will not add anything to a line of code
#define MAX
int x = 1 + 2; MAX // here MAX does nothing
but what an empty define does is allow you to conditionally do certain things like
#ifdef DEBUG
// do thing
#endif
Similarly header guards use the existance of a macro to indicate if a file has already been included in a translation unit or not.
The C Preprocessor (CPP) creates a definitions table for all variables defined with the #define macro. As the CPP passes through the code, it does at least two things with this information.
First, it does a token replacement for the defined macro.
#define MAX(a,b) (a > b) ? (a) : (b)
MAX(1,2); // becomes (1 > 2) ? (1) : (2);
Second, it allows for those definitions to be searched for with other preprocessor macros such as #ifdef, #ifndef, #undef, or CPP extensions like #if defined(MACRO_NAME).
This allows for flexibility in using macro definitions in those cases when the value is not important, but the fact that a token is defined is important.
This allows for code like the following:
// DEBUG is never defined, so this code would
// get excluded when it reaches the compiler.
#ifdef DEBUG
// ... debug printing statements
#endif
#define does a character-for-character replacement. If you give no value, then the identifier is replaced by...nothing. Now this may seem strange. We often use this just to create an identifier whose existence can be checked with #ifdef or #ifndef. The most common use is in what are called "inclusion guards".
In your own preprocessor implementation, I see no reason to treat this as a special case. The behavior is the same as any other #define statement:
Add a symbol/value pair to the symbol table.
Whenever there is an occurrence of the symbol, replace it with its value.
Most likely, step 2 will never occur for a symbol with no value. However, if it does, the symbol is simply removed since its value is empty.
According to cplusplus.com, the syntax to define a macro is:
#define identifier replacement
However, I sometimes stumble upon a macro definition which doesn't contain a replacement. For example in afxwin.h, there is the following preprocessor definition:
#define afx_msg // intentional placeholder
My questions:
What happens at compile-time when a preprocessor definition that doesn't have a replacement is used? Is it simply ignored? For example, does the line afx_msg void OnAddButton(); become void OnAddButton();?
What is the purpose of using preprocessor without replacement? Is it simply to make code more clear?
"Nothing" (no text) is a valid replacement text for a macro. It will simply be removed (more precisely, replaced by nothing) by the preprocessor.
There are multiple reasons why you'd use something like this. One is to simply use the macro in #ifdef and similar constructrs.
Another is conditional compilation. A typical use case is public APIs and DLL exports. On Windows, you need to mark a function as exported from a DLL (when building the DLL) or as imported from a DLL (when linking against the DLL). On ELF systems, no such declarations are necessary. Therefore, you'll often see code like this in public library headers:
#ifdef _WIN32
#ifdef BUILDING_MYLIB
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
#else
#define MYLIB_API
#endif
void MYLIB_API myApiFunction();
Yet another reason could be code processing tools. Perhaps you have a tool which parses source code, extracting a list of functions with a certain marker. You can define such a marker as an empty macro.
#define bla
simply defines bla.
you can use it with
#ifdef bla
...
place some code here
...
#endif
a typical use case is #define DEBUG to enable special code parts in debugging mode.
Another way to set such things from "outside" is:
g++ -DDEBUG x.cpp
which also sets the macro DEBUG defined.
And every header file should have something like:
#ifndef THIS_HEADER_INCLUDE_GUARD
#define THIS_HEADER_INCLUDE_GUARD
...
rest of header file
...
#endif
This simply protects your header file for (recursivly) read more the once.
Some can be done with implementation specific #pragma once.
the preprocessor processes it, removing it and replacing it with nothing
could be a variety of reasons, including readability, portability, custom compiler features, etc.
I would like something like:
#define C_OR_CPP(C__, CPP__) #ifdef __cplusplus\
CPP__\
#else\
C__\
#endif
Is it possible?
Maybe some dirty hack with #include ?
Reason:
I make a header where a struct uses a member variable of type vector<stuff>*, but in C i want it to simply be void*, you know.
TIA
What's the problem with
#ifdef __cplusplus
#define C_OR_CPP(C, CPP) CPP
#else
#define C_OR_CPP(C, CPP) C
#endif
(Leaving names with double underscore to the implementation per phresnel remark)
My English is poor, and I'm sorry for language mistakes and typos if any.
If #ifdef must not wrap the macro invocation, there is a solution not so graceful.
g++ only:
You may try this in selective occasions. But if there are commas in a or b, workarounds are still needed.
It's simply based on the fact that __cplusplus is defined to "1" when in a C++ environment and remains itself while not.
#define SELECT1(a, b) a
#define SELECT__cplusplus(a, b) b
#define xcat(a,b) a##b
#define concat(...) xcat(__VA_ARGS__)
#define C_OR_CPP(C, CPP) concat(SELECT, __cplusplus)(C, CPP)
C_OR_CPP(1, 2)
Other Environments
Check the __cplusplus macro, a compiler that comforming to standard C++ should generate
#define __cplusplus value
and value should >= 199711L
Not in C++. But you can
#ifdef __cplusplus
# define CPP
#else
# define C
#endif
I assume this is just a pathological example by you. Note also that double underscore is reserved to library implementors (see 17.6.4.3.2 Global names).
vector, but in C i want it to simply be void, you know.
So, what speaks against a solution like
struct Foo {
#ifdef __cplusplus
...
#else
...
#endif
};
or what speaks against providing different APIs for different programming languages?
AProgrammer already given you the right answer, but the answer to the "is it possible" part of the question is no. Macro expansion doesn't occur until after all preprocessor directives have been handled, so any macro that expands into a #define or #ifdef will be passed to the compiler as regular source text, which will cause the compiler to yak.
I want to have more control over macros such as assertions (and some logging macros that are not directly under my control). So I decided to do something like this, expecting it to work (in case somebody is wondering, the reason it does not work is that the last undef of MY_ASSERT_COPY invalidates MY_ASSERT right before it).
#ifndef ENABLE_FULL_ERROR_ASSERTS
#define MY_ASSERT_COPY MY_ASSERT
#undef MY_ASSERT
#define MY_ASSERT
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT MY_ASSERT_COPY
#undef MY_ASSERT_COPY
#endif
Now I know a few ways around it, one being to define another macro for assertions just for that file, which I can then turn off without affecting assertions in any other part of the program. I initially thought this was a really elegant solution (before I found out it did not compile) that will allow me to use MY_ASSERT everywhere and then simply turn it off for particular files.
Since the above doesn't work, is there a workaround that will allow me to selectively kill the macro without affecting the surrounding code and without defining another substitute macro like #define MY_ASSERT_FOR_VECTORS MY_ASSERT
Some compilers provide #pragma push_macroand #pragma pop_macro to save and restore macro state.
Limited portability though.
This may not work in all situations, but maybe you could simply undef the macros, define them as you wish and then undef them again.
The next time your code uses some of these macros it should #include the header files where they were initially defined so it will define those macros again.
One safe option would be:
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#define MY_ASSERT ....
#endif
// Code for my current class, which happens to be header only
#ifndef ENABLE_FULL_ERROR_ASSERTS
#undef MY_ASSERT
#include "headers.h" //etc
// line above should redefine the macros
#endif