In the C/C++ there are 2 types of macro:
#define ABC /* usual */
und
#define FUNC(a) /*function-like*/
But how can I undefine them?
Update: So there is no difference between undefing "constant-like macro" and "function-like macro"?
#undef ABC
#undef FUNC
#undef "cancels" out a previous #define. The effect is as though you never had a previous #define for a particular identifier. Do note that #defines do not respect scope, so it's best to use them only when you need to.
Also note that it doesn't matter if one macro identifier uses the "usual" syntax while another uses a "function-like" syntax. #define ABC and #define ABC(A) both define a macro named ABC. If you have both, without #undefing one of them, the latest one "overrides" the other. (Some compilers may emit a warning if this happens.)
#undef ABC
#undef FUNC
Related
In a codebase that can be built as either C or C++, I thought I'd make a macro to take advantage of static_assert in the case it's built as C++11 or higher.
(Note: I know there are ways to do this in pre-C11 C, at least if you're willing to take a message parameter--though it won't work quite everywhere. But for the sake of argument let's say I have some legitimate need to make it take no message, and be a no-op in at least some C builds.)
So here was the simple definition I tried:
#if defined(__cplusplus) && __cplusplus >= 201103L
#define STATIC_ASSERT(cond) \
static_assert((cond), #cond)
#else
#define STATIC_ASSERT(cond)
#endif
There's no semicolon in the macro, with the intent that you would add it at the callsite. But under pedantic C warning settings, this macro appearing in global scope causes:
error: ISO C does not allow extra ‘;’ outside of a function [-Werror=pedantic]
The easy solution seems to be to take the semicolon off the callsites, and put it in the C++11 side of the macro. But I wonder: how do you make a no-op macro in global scope which allows a semicolon at the callsite (without running afoul of some other warning)?
Since forward declarations of structures may be repeated as much as we want, you can use a dummy declaration:
#define STATIC_ASSERT(cond) struct GlobalScopeNoopTrick
#JonathanLeffler says this should work in older compilers, even pre-C11...but:
"If you have a C90 compiler, it would object if you had a static assert after a statement in a compound statement. This is not your primary concern (it’ll always be OK at file scope if the static assert is OK too), but it isn’t limited to being used at file scope. The risk is low, though"
For related situations that might not be entirely no-ops at compile-time, C11 introduced the ability to repeat typedefs. And as in the post linked about static asserts in C prior to _Static_assert() shows, there are ways to get around typedef duplication for older C using the line number or another disambiguator:
/* Standard indirection to allow concatenation after expansion */
#define CONCAT(a,b) CONCAT_(a,b)
#define CONCAT_(a,b) a##b
#if defined(__cplusplus) && __cplusplus >= 201103L
#define STATIC_ASSERT(cond) \
static_assert((cond), #cond)
#else
#define STATIC_ASSERT(cond) typedef void CONCAT(dummy_unused_,__LINE__)
#endif
So long as static assertions appear one per line the identifiers won't conflict with each other.
In many places I see the usage of undefine macro before defining the same macro. For example:
#undef FORMULA
#ifdef SOMETHING
#define FORMULA 1
#else
#define FORMULA 2
#endif
What for the #undefine FORMULA used?
I may guess that it deals with the case when the macro was already defined before. But isn't the new definition overrides the old one? Thanks!
A macro name currently defined cannot be redefined with a different definition (see below), so #undef allows that macro name to be redefined with a different definition.
Here's the relevant legalese:
Both C and C++ Standards (same wording):
A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit.
Slight differences in wording, same meaning:
C Standard (N1256), §6.10.3/2:
An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
C++ Standard (N3337) §16.3/2
An identifier currently defined as an object-like macro may be redefined by another #define preprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical, otherwise the program is ill-formed. Likewise, an identifier currently defined as a function-like macro may be redefined by another #define preprocessing directive provided that the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical, otherwise the program is ill-formed.
Same wording in both Standards:
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
So:
#define X(y) (y+1)
#define X(z) (z+1) // ill-formed, not identical
IMHO, using #undef is generally dangerous due to the scoping rules for preprocessor macros. I'd prefer to get a warning or error from the preprocessor and come up with a different preprocessor macro rather than have some translation unit silently accept a wrong macro definition that introduces a bug into the program. Consider:
// header1.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x400
// header2.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x410
and have a translation unit #include both headers. No warning, probably not the intended result.
Yes, the new definition overrides all previous. But there is corresponding warning message. With #undef you have no warnings.
But isn't the new definition overrides the old one?
Yes, it does (when your compiler allows it). However, redefining a macro results in a compiler warning, which using #undefine lets you avoid.
This may be important in programming shops with strict rules on compiler warnings - for example, by requiring all production code to be compiled with -Werror flag, which treats all warnings as errors.
#undef removes the macro, so the name is free to be defined again.
If the macro was never defined in the first place, #undef has no effect, so there's no downside. #undef … #define should be read as replacing any potential previous definition, but not to imply that it must already be defined.
Popular compilers do allow you to skip the #undef, but this is not allowed by the official standard ISO C and C++ language specifications. It is not portable to do so.
A bunch of code just got handed over to me and I got baffled by macros in the header. I could not understand what they are for:
#define WRAPPER_MACRO(symbol) symbol
#define ANOTHER_SYMBOL WRAPPER_MACRO(ANOTHER_SYMBOL)
#define PREFIXED_ANOTHER_SYMBOL WRAPPER_MACRO(PFX_ANOTHER_SYMBOL)
Why do this? What is the benefit?
Edit: This is not the actual verbatim code from my codebase but it has the same template. I just replaced macro names.
As #Michael said, we'll need to see the real macros to know for sure. But without them, I'm willing to take a few guesses that might help you out.
The macro nesting is probably a stringification thing. This bit of code is from a codebase I maintain:
// As per http://gcc.gnu.org/onlinedocs/cpp/Stringification.html:
// "If you want to stringify the result of expansion of a macro argument, you
// have to use two levels of macros."
#ifndef STRINGIFY
#define STRINGIFY(s) TOSTRING(s)
#define TOSTRING(s) #s
#endif
I'm also guessing your PREFIXED_ANOTHER_SYMBOL macro is doing something similar to this, using the # or ## preprocessor directives to prepend a certain symbol to whatever you feed the macro.
I am wondering how I can conditionally define function macros. For instance, suppose I have a function macro called SETBIT. I would like to define my own version of it should someone using my library not include a separate header file where such a macro function would have already been defined. The reason for this is portability among different compilers.
So, I know that I can do this with constants as follows:
#ifndef X
#define X 10
#endif
I would like to do something similar with a function macro
#ifndef SETBIT
#define SETBIT(port,bit) ((port) |= (1 << (bit)))
#endif
However, I don't believe this will work.
However, I don't believe this will work.
What leads you to believe that? It will work (provided that you fix the typo - it should read #ifndef SET_BIT, I suppose).
I was investigating a compile and link issue within my program when I came across the following macro that was defined in a header and source file:
/* file_A.c */
#ifndef _NVSize
#define _NVSize 1
#endif
/* file_B.c */
#include "My_Header.h"
#ifndef _NVSize
#define _NVSize 1
#endif
/* My_Header.h */
#define _NVSize 1024
Nothing out of the ordinary yet, until I saw the following information in the GCC output map file:
/* My Map File */
...
.rodata 0x08015694 _NVSize
...
My understanding of the map file is that if you see a symbol in the .rodata section of the map file, this symbol is being treated as a global variable by the compiler. But, this shouldn't be the case because macros should be handled by the preprocessor before the compiler even parses the file. This macro should be replaced with it's defined value before compiling.
Is this the standard way that GCC handles macros or is there some implementation specific reason that GCC would treat this as a global (debug setting maybe)? Also, what does this mean if my macro gets redefined in a different source file? Did I just redefine it for a single source file or did I modify a global variable, thereby changing _NVSize everywhere it's used within my program?
I think the compiler is free to assign your macro to a global variable as long as it ensures that this produces the exact same result as if it did a textual replacement.
During the compilation the compiler can mark this global specially to denote that it is a macro constant value, so no re-assignment is possible, no address can be taken, etc.
If you redefine the macro in your sorce, the compiler might not perform this transformation (and treat it as you'd expect: a pre-compier textual replacement), perform it on one of the different values (or on all of them say, using different names for each occurrance), or do domething else :)
Macros are substituted in the preprocessor step, the compiler only sees the substituted result. Thus if it sees the macro name, then my bet is that the macro wasn't defined at the point of usage. It is defined between the specific #define _NVSize and an #undef _NVSize. Redefining an existing macro without using an #undef first should result in a preprocessor error, AFAIR.
BTW, you shouldn't start your macro names with an underscore. These are reserved for the implementation.