I need to temporarily overwrite a macro and then restore it. Like:
#define FOO X
#save FOO
#define FOO Y
...
#restore FOO
Is it possible in standard C preprocessor? In GCC?
ADDED. About real world example. I use a global macro for error exception. It acts like assert, but for persistent usage, not only for debug versions; so, for example, I usually call functions (with side-effect) inside the macro. It's defined once, but the definition isn't persistent; therefore I don't know it a-priori. For some piece of code I need its own, modified version of the macro, but I want to save general style of code. It's looks ugly when one part of code uses the one macro, other part uses other macro -- both macros have the same purpose, but slightly different implementation.
So, it's good for me to save original macro temporarily, use different version for a part of code, after that restore original macro.
This is possible with #pragma push_macro and #pragma pop_macro. These are not standard C—they're originally an MSVC extension—but clang supports them, and so does GCC.
Example usage:
int main() {
#define SOME_MACRO 1
printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma push_macro("SOME_MACRO")
#define SOME_MACRO 2
printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma pop_macro("SOME_MACRO")
printf("SOME_MACRO = %d\n", SOME_MACRO);
return 0;
}
prints:
SOME_MACRO = 1
SOME_MACRO = 2
SOME_MACRO = 1
You can also #undef a macro inside a push_macro / pop_macro pair, and the pop_macro call will redefine it.
As already said, it is not really possible. Depending on the situation, this might be a workaround:
#include "generalmacrodefs.h" // put them in here or include them indirectly
#undef macro1
#define macro1 "specialized temporary value"
#undef macro1
#include "generalmacrodefs.h" // restores
This requires that generalmacrodefs.h uses a pattern like this at least for the definitions you might temporarily overwrite:
#ifndef macro1
#define macro1 "original value"
#endif
The closest you can come in C is the #undef directive, which simply undefines the macro, allowing it to be replaced:
#define FOO X
...
#undef FOO
#define FOO Y
...
#undef FOO
#define FOO X
The problem is that you cannot know the 'old' value of FOO once you redefine it - so your values must be hard-coded in one place.
You cannot create a macro to save the values for you either, as it isn't possible to have a macro that creates other preprocessor directives in standard C.
Related
Is there a way to restore macros in C, so that you can define a new macro, under which name probably other macros are already defined, and redefine it with the previous value?
so that when new defined macros are deleted and eventually redefined macros are resetted to its previous state?
Example:
// a macro parameter used in a library
#define size 10
#include <library/use_size.h>
//here the command/pragma to save the definitions
#define size (100 / sizeof(size_t))
// some use of size ...
//here the command/pragma to reset the definitions
#include <library/allocator_with_size.h>
#undef size
// use size as a variable name
size_t size = 0;
//...
size += 123;
Edit: I do not want to use #undef, because it does not restore old macros. Also, if you have many macros, eg for using them in a X-macro-list (in a long repetitive code/declaration of constant arrays and structs), it looks ugly, if there are many #undef directives.
Ok I researched myself and found the pragmas push_macro and pop_macro, supported by clang, gcc and visual c++. I use clang, so it is no problem to use it. The disadvantage: it does not reduce the line-count if you want to restore multiple macros ¹, but it restores the macros and can be encapsulated:
#pragma push_macro("size")
#define size (100 / sizeof(size_t))
#pragma pop_macro("size")
Notes:
¹ I defined multiple macros and tried to restore them with:
#pragma push_macro("size", "key", "name")
// define them all
#pragma pop_macro("size", "key", "name")
But that is not implemented into the compilers yet. So for each macro there must be a seperate line to do this.
I have a file that uses a FLAGS macro from an include that I do not control. What is in FLAGS is not consistent. Occasionally I need to change FLAGS to add a flag to it. Now I know I can't do #define FLAGS FLAGS|MY_FLAG, but I thought if I stored FLAGS in a temporary variable that I could then undefine it and redefine it using the temporary and my flag. For example:
// Assume this next line is what's in the include file
#define FLAGS (1|2|4)
// The rest of this is source, assume compile with -DMOD
#ifdef MOD
#define TEMP (FLAGS|8)
#undef FLAGS
#define FLAGS TEMP
#endif
int main()
{
printf("0x%x\n", FLAGS);
}
And if MOD is defined the error is error: 'FLAGS' was not declared in this scope. I know that I can change all the actual C code that uses FLAGS to instead use FLAGS|MY_FLAG but I was hoping to modify the macro rather than all the code.
Your only real way to do exactly what you are trying to do is to define an additional macro
// Assume this next line is what's in the include file
#define FLAGS_FOR_A (1|2|4)
#define FLAGS FLAGS_FOR_A
// The rest of this is source, assume compile with -DMOD
#ifdef MOD
#undef FLAGS
#define FLAGS ( FLAGS_FOR_A | 8 )
#endif
int main()
{
printf("0x%x\n", FLAGS);
}
Macros just do simple text replacement, computed before runtime
You can do something logically equivalent to #define FLAGS FLAGS|MY_FLAG if you define the macro as modifiable using Boost's "evaluated slots":
#include <boost/preprocessor/slot/slot.hpp>
// define FLAGS as a modifiable macro and create a setter for it
#define FLAGS BOOST_PP_SLOT(1)
#define UPDATE_FLAGS BOOST_PP_ASSIGN_SLOT(1)
int main(void) {
// set the initial value of FLAGS
#define BOOST_PP_VALUE (1|2|4)
#include UPDATE_FLAGS
printf("0x%x\n", FLAGS); // 0x7
// update FLAGS with a new value using the old one
#define BOOST_PP_VALUE (FLAGS|8)
#include UPDATE_FLAGS
printf("0x%x\n", FLAGS); // 0xf
}
Despite being witchcraft, this is completely standard-compliant C, no extensions. Only works for integers.
(It works by taking advantage of something important: macros aren't just expanded into program code, but also need to be expanded to determine whether to follow an #if branch as well. Since #if directives are also capable of evaluating integer math, this is able to expand the actual numeric value and use it to construct a new expansion for the PP_SLOT that doesn't involve a reference to any macro name. This is all hidden behind the #include UPDATE_FLAGS directives.)
On Apple's opensource website, the entry for stdarg.h contains the following:
#ifndef _STDARG_H
#ifndef _ANSI_STDARG_H_
#ifndef __need___va_list
#define _STDARG_H
#define _ANSI_STDARG_H_
#endif /* not __need___va_list */
#undef __need___va_list
What do the #define statements do if there's nothing following their first argument?
There are sort of three possible "values" for an identifier in the preprocessor:
Undefined: we don't know about this name.
Defined, but empty: we know about this name, but it has no value.
Defined, with value: we know about this name, and it has a value.
The second, defined but empty, is often used for conditional compilation, where the test is simply for the definedness, but not the value, of an identifier:
#ifdef __cplusplus
// here we know we are C++, and we do not care about which version
#endif
#if __cplusplus >= 199711L
// here we know we have a specific version or later
#endif
#ifndef __cplusplus // or #if !defined(__cplusplus)
// here we know we are not C++
#endif
That's an example with a name that if it is defined will have a value. But there are others, like NDEBUG, which are usually defined with no value at all (-DNDEBUG on the compiler command line, usually).
They define a macro which expands to nothing. It's not very useful if you intended it to be used as a macro, but it's very useful when combined with #ifdef and friends—you can, for example, use it to create an include guard, so when you #include a file multiple times, the guarded contents are included only once.
You define something like:
#define _ANSI_STDARG_H_
so that, later you can check for:
#ifdef _ANSI_STDARG_H_
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
If I have a constant defined as such in a header file:
#define MY_CONSTANT 1
And I include a library to the whole project which includes a different definition for the same constant:
#define MY_CONSTANT 0
I naturally get conflicts while compiling. Supposing that I cannot alter my project code and that I can only change my library code, what can I do to make MY_CONSTANT as defined by my lib?
EDIT:
just to clarify, my goal is to update a constant in my code through a library. Because I'm writing a library to simulate hardware functions, I have to go by the rule that the software itself must be untouched. There is a loop of sort in the main file that uses the constant. I need to change this constant, but without actually altering it in the main file.
You can undefine the other definition
#ifdef MY_CONSTANT
#undef MY_CONSTANT
#endif
#define MYCONSTANT 0
Also, you should remove the =, and the ;
P.S. as mentioned, it will not change the code that already compiled.
You can #undef MY_CONSTANT and redefine to the value you want, but that's just asking for trouble. See if you can modify the design entirely so that MY_CONSTANTs don't clash.
Undef, redef, and then redef it back
#ifdef MY_CONSTANT
#undef MY_CONSTANT
#endif
#define MY_CONSTANT 0
/* code here */
#undef MY_CONSTANT /* not needed if you don't need the library's definition*/
#include "library.h" /* file that originally defined it
might not work if include guards prevent it
in that case #undef LIBRARY_H
although that causes more trouble :( */