How do I temporarily disable a macro expansion in C/C++?
In MSVC you could use push_macro
pragma, GCC supports it for compatibility with Microsoft Windows compilers.
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
How to disable macros imported from C-Header
You already know about the #undef
option, which would do what you need.
There is another option however. You could completely hide the fact that your A
uses library C
from your users: Define your own types and interface in the header and class definition of A
and remove the library include from your A
header. Then in your implementation file you can include the library header and utilize the library in whatever manner is needed, all the while hiding the include of the c_library.h
from your users. This has the added advantage of reducing the coupling between your class users, your class, and the library that it depends on.
How to disable macro function?
The idea is for the macro to do nothing on release builds. You could define it to an empty string literal, since "";
is a valid expression. I would believe the reason of being defined to ((void)0)
is so that the implementation does not emmit warnings for the expression. I have no solid grounds to say this, but some minimal testing shows that "";
generates a warning while ((void)0)
doesn't. Of course, warnings are not standarized so there could be a particular implementation that does emit a warning for ((void)0)
as well, but it would have to define assert
to something else that doesn't on NDEBUG
builds or it would be quite annoying to the user.
Temporarily overwrite a macro in C preprocessor
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
CPP: avoiding macro expansion of a macro function parameter
I'm doing:
#include <cstdio>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, lib, str) printf("%s\n", #lib);
#define LOG(ptr, lib, str) LOG_SIMPLE(ptr, ##lib, str)
int main()
{
LOG_SIMPLE(0, FOO, "some error");
LOG(0, BAR, "some other error");
}
which prints out:
FOO
BAR
Works with MSVC2005 but not with gcc/g++.
EDIT: to make it work with gcc/g++ you can abuse variadic macros:
#include <stdio.h>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, str, lib) printf("%s\n", #lib);
#define LOG(ptr, str, lib, ...) LOG_SIMPLE(ptr, str, lib##__VA_ARGS__)
int main()
{
LOG_SIMPLE(0, "some error", FOO);
LOG(0, "some other error", BAR);
LOG(0, "some other error", FOO, BAR);
}
However, it's your discipline not to use the macro with too many parameters. MSVC2005 prints out
FOO
BAR
FOO2
while gcc prints out
FOO
BAR
FOOBAR
C++ Stop Preprocessor Macro Expansion
What you're trying to do is not possible, as Michael Karcher's answer states: #define delete
already makes the program ill-formed, and expanding an object-like macro (outside its own expansion) cannot be avoided.
However, for your particular use case detailed in the question, a workaround is possible. You could put your #define delete
into a header file (let's call it debug_delete.hxx
), like this:
#ifdef delete
# undef delete
#endif
#define delete MyCustomDelete(__FILE__, __LINE__), delete
Then, create another header file (let's call it normal_delete.hxx
):
#ifdef delete
# undef delete
#endif
Note in particular that there is no mechanism in these headers to prevent multiple inclusion; in fact, we want them includable an arbitrary number of times.
Then, wrap code which must use = delete;
in appropriate #include
directives:
class A {
#include "normal_delete.hxx"
A() = delete;
#include "debug_delete.hxx"
~A() { delete p; }
};
(Yes, it's ugly, but what you're doing is sort of ugly in the first place, so ugly code may be required to make it work).
How to disable a warning within a C++ macro
In your case you have to use the extension __pragma
__pragma
instead of
#pragma
Suppress C Macro Variable Substitution
You can define a different macro to expand to name
, like this:
#define Name name
and change the name
field in the PRIMITIVE
macro to use the new macro, like this:
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->Name = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
Other than using something different from the parameter name in the macro body or changing the parameter name, there is no other way to do this in the C language. Per C 2011 (N1570) 6.10.3.1 1, when a function-like macro is recognized, parameter names are immediately substituted except when #
or ##
is present, and there no other exceptions:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.
The #
token changes the parameter name to a string, which is no use in this situation. The ##
token expands the parameter name and pastes it together with an adjacent token, which is also no use in this situation.
Related Topics
How to Detect Region of Large # of White Pixels Using Opencv
"Proper" Way to Store Binary Data with C++/Stl
What Use Are Const Pointers (As Opposed to Pointers to Const Objects)
Should I Use Printf in My C++ Code
Visual Studio: Link:Fatal Error Lnk1181: Cannot Open Input File
Is 'Bool' a Basic Datatype in C++
What Are Customization Point Objects and How to Use Them
Qt: How to Handle the Event of the User Pressing the 'X' (Close) Button
What's the C++ Suffix for Long Double Literals
What Is the Performance Impact of Using Int64_T Instead of Int32_T on 32-Bit Systems
How to Create and Initialize an Array of Values Using Template Metaprogramming
How to Use Qt Without Qmake or Qt Creator
Why Can't I Inherit from Int in C++