Here is my example code https://godbolt.org/z/VKgKik
#define delete MyCustomDelete(__FILE__, __LINE__), delete
#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))
class A {
A() = CAT_3(de,le,te);
};
The godbolt example is setup to display the preprocessor output. The goal is that at the end of the preprocessor pass i want the output code to be
class A {
A() = delete;
};
currently "ThisShouldNotshowUp" is displayed there instead. I thought the use of the ## operator would stop the preprocessor from reexpanding but it did not.
I realize removing the "#define delete" would solve the problem but I need this define there. The reason I have created a macro with the same name as delete is because I want to be able to track the news and deletes, and If a memory leak occurs I can see what line of code aloced it. This macro thus means I can continue to use the keyword delete in my code and the File and line numbers get filled in for free. As far as i know there is no other way to achieve this functionailty except by defined a delete macro. This is the crux of the problem. The delete macro has given me a powerful debug tool however it has removed a useful language feature for me to use.
You have no chance in creating a preprocessing token that is the name of an object-like macro from expanding a macro. The relevant section of n3337 is [cpp.rescan]. I quote a shortened part of the first paragraph in it.
After all parameters in the replacement list have been substituted and # and ## processing has taken place [...]. Then the resulting preprocessing token sequence is rescanned [...] for more macro names to replace.
Nonwithstanding the problem, that delete is technically forbidden to be a macro name, there is no way to prevent the macro name to be recognized while rescanning.
You probably mixed up the fact that ## operator does use it's parameters without expansion with the idea that the result of ## doesn't undergo 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).
Presumably you want to use a macro so you can turn on and off your delete tracking. If you're only using this on your source, and not trying to rig it up to transform existing C++, you could use a function-like macro in order to effect the optional tracking that you desire.
#define TRACK_DELETES 0
#if TRACK_DELETES
#define DELETE( a ) \
do { MyCustomDelete( __FILE__, __LINE__ ); delete (a); } while (0)
#define DELETEALL( a ) \
do { MyCustomDelete( __FILE__, __LINE__ ); delete [] (a); } while (0)
#else
#define DELETE( a ) do { delete (a) ; } while(0)
#define DELETEALL( a ) do { delete [] (a) ; } while(0)
#endif
int main(){
DELETE( A );
DELETEALL( B );
return 0;
}
See if this does what you want with TRACK_DELETES set to 0 or 1 under gcc -E.
You'll want to leave the bare delete keyword alone so it can be used appropriately.
Related
I want to make a conditional preprocessor macro. The thing I want to do is like DEBUG(LEVEL, MESSAGE) and I want it to behave like if I wrote:
#ifdef(LEVEL)
std::cout<<MESSAGE<<std::endl;
#endif
Is there a way to do that in C++?
This is just an extra reading confort I want to give to myself, it is not really important.
Yes you can:
#define LEVEL 100
#if LEVEL == 100
std::cout<< "whatever";
#endif
you can find a list do directives here
EDIT: you can also do something like this:
#define DEBUG(X,MESSAGE) if(X==100)std::cout<<MESSAGE<<endl;
Good Information on pre-processor instructions can be found here and here.
I'd personally recommend the second link, as it's heavily edited.
Answer to your code snippet:
enum level
{
m_00,
m_01,
m_02,
};
// Create: Global Instruction
#define Args(_instruction_,_level_,_output_)\
_instruction_==_level_?printf(_output_):0;
#define Foo 1 // Example
void main( )
{
Args( Foo, level::m_01, "Level has been verified..." )
};
Obviously you can change this to fit your needs, but the idea is still the same.
I have two pieces of code I need to make running. (No, I am not allowed to change either of them).
First piece defines a macro
#define MACRO do { /* stuff in multiple lines and do not return a value */ } while (0)
Second piece uses another macro in an if statement
if (ANOTHER_MACRO) { /* do some stuff */ }
I need to make ANOTHER_MACRO use MACRO and I am allowed to define ANOTHER_MACRO.
I thought an inline function would be the right way to do it, but neither by using macros nor by using inline functions I could get it work. Any suggestions?
Just insert a function to call MACRO on one side and return a value on the other.
#define ANOTHER_MACRO theFunc()
bool theFunc() {
MACRO;
return /* something */;
}
I would like to create a custom version of the assert macro defined in <cassert>, that displays an error message when the assertion fails.
Desired usage:
custom_assert(AClass<T1, T2>::aBoolMethod(), "aBoolMethod must be true");
Flawed test implementations:
#define custom_assert(mCondition, mMessage) ...
// This fails because mCondition may have commas in it
#define custom_assert(..., mMessage)
// Not sure about this either - mMessage may be an expression containing commas
// as well
How can I correctly implement a custom assert that takes a boolean expression (with possible commas) as the first argument and a string expression (with possible commas) as the second argument?
Or is there a way to implement assertions without the use of macros?
You were quite close, what you need to use is simply this:
#define myAssert(message, ...) do { \
if(!(__VA_ARGS__)) { \
/*error code*/ \
} \
} while(0)
The special preprocessor variable __VA_ARGS__ will expand to whatever was passed in the place of the three dots, including all comas.
Note that the preprocessor will not interprete commas in the condition in the very least, it will just paste them as is into the if() statement. Which is precisely what you want if you want to pass templated conditions, as hinted by the comments.
Commas in the message string are not a problem either, since the preprocessor understands about string literals and does not interprete anything within the double quotes.
The straightforward
assert(AClass<T1, T2>::aBoolMethod() && "aBoolMethod must be true");
fails:
error: macro "assert" passed 2 arguments, but takes just 1
but if you add an extra pair of parenthesis around the first argument, it works. Like this:
#include <cassert>
template <typename A, typename B>
struct C {
bool f() { return false; }
};
int main() {
assert((C<int,int>().f()) && "some message, with comma");
// ^ ^
}
Note: it was also pointed out by Adam Rosenfield in a comment.
Perhaps the only benefit over the __VA_ARGS__ approach is that it doesn't dump yet another macro on the user. If you forget the parenthesis, you can get a compile time error, so I see it as a safe solution.
For the sake of completeness, I published a drop-in 2 files assert macro implementation in C++:
#include <pempek_assert.h>
int main()
{
float min = 0.0f;
float max = 1.0f;
float v = 2.0f;
PEMPEK_ASSERT(v > min && v < max,
"invalid value: %f, must be between %f and %f", v, min, max);
return 0;
}
Will prompt you with:
Assertion 'v > min && v < max' failed (DEBUG)
in file e.cpp, line 8
function: int main()
with message: invalid value: 2.000000, must be between 0.000000 and 1.000000
Press (I)gnore / Ignore (F)orever / Ignore (A)ll / (D)ebug / A(b)ort:
Where
(I)gnore: ignore the current assertion
Ignore (F)orever: remember the file and line where the assertion fired and
ignore it for the remaining execution of the program
Ignore (A)ll: ignore all remaining assertions (all files and lines)
(D)ebug: break into the debugger if attached, otherwise abort() (on Windows,
the system will prompt the user to attach a debugger)
A(b)ort: call abort() immediately
You can find out more about it there:
blog post
GitHub project
Hope that helps.
I'm not entirely sure what you mean by a "boolean expression with commas." Simply wrapping macro expansions in commas (as seen in the samples below) protects against parse errors if you happen to use the default comma operator in your conditions, but the default comma operator does not do the same thing as &&. If you mean you want something like:
my_assert(condition1, condition2, message1, message2);
You're out of luck. How should any API tell where the conditions stop and the messages start. Just use &&. You can use the same tricks below for handling the message portion to also create a my_condition_set macro that allows you to write something like:
my_asssert(my_condition_set(condition1, condition2), message1, message2);
Getting to the message part, which is the tricky part and the most useful part that the standard assert macros tend to lack, the trick will come down to either using a custom message output type that overrides operator, (the comma operator) or to use a variadic template.
The macro uses variadic macro support and some tricks to deal with commas. Note that none of the code I'm posting here is tested directly; it's all from memory from custom assert macros I've written in the past.
The version using comma operator overloading, which works in C++98 compilers:
struct logger {
template <typename T>
logger& operator,(const T& value) {
std::cerr << value;
return *this;
}
};
#define my_assert(condition, ...) do{ \
if (!(condition)) { \
(logger() , __VA_ARGS__); \
std::terminate(); \
} \
}while(false)
The logger() expression creates a new instance of the logger type. The list of arguments from __VA_ARGS__ is then pasted with commas separating each. These commas each invoke the comma operator left-to-right, which forwards the expression on to std::cerr. I usually use a custom log stream that handles writing to files, cerr, Windows' OutputDebugStringA, or whatever.
Using variadic templates in a C++11 compiler, this would be more like:
template <typename ...Ts>
void logger(Ts&&... argv) {
std::cerr << your_string_format_function(argv...);
}
void logger(const char* fmt) {
std::cerr << fmt;
}
void logger() {}
#define my_assert(condition, ...) do{ \
if (!(condition)) { \
logger(__VA_ARGS__); \
std::terminate(); \
} \
}while(false)
You'd need a format string function that actually works with variadic arguments or write an adapter for something like boost::format.
You could also use printf if you don't mind the lack of type-safety.
Recently I have been reading Effective C++ Second Edition by Scott Meyers to improve on C++ best practices. One of his listed items encourages C++ programmers to avoid pre-processor macros and 'prefer the compiler'. He went as far as saying there are almost no reasons for macro in C++ aside from #include and #ifdef/#ifndef.
I agree with his reasoning, as you can accomplish the following macro
#define min(a,b) ((a) < (b) ? (a) : (b))
with the following C++ language features
template<class T>
inline const T & min(const T & a, const T & b) {
return a < b ? a : b;
}
where inline gives the compiler the option to remove the function call and insert inline code and template which can handle multiple data types who have an overloaded or built in > operator.
EDIT-- This template declaration will not completely match the stated macro if the data type of a and b differ. See Pete's comment for an example.
However, I am curious to know if using macros for debug logging is a valid use in C++. If the method I present below is not good practice, would someone be kind to suggest an alternative way?
I have been coding in Objective-C for the last year and one of my favorite 2D engines (cocos2d) utilized a macro to create logging statements. The macro is as follows:
/*
* if COCOS2D_DEBUG is not defined, or if it is 0 then
* all CCLOGXXX macros will be disabled
*
* if COCOS2D_DEBUG==1 then:
* CCLOG() will be enabled
* CCLOGERROR() will be enabled
* CCLOGINFO() will be disabled
*
* if COCOS2D_DEBUG==2 or higher then:
* CCLOG() will be enabled
* CCLOGERROR() will be enabled
* CCLOGINFO() will be enabled
*/
#define __CCLOGWITHFUNCTION(s, ...) \
NSLog(#"%s : %#",__FUNCTION__,[NSString stringWithFormat:(s), ##__VA_ARGS__])
#define __CCLOG(s, ...) \
NSLog(#"%#",[NSString stringWithFormat:(s), ##__VA_ARGS__])
#if !defined(COCOS2D_DEBUG) || COCOS2D_DEBUG == 0
#define CCLOG(...) do {} while (0)
#define CCLOGWARN(...) do {} while (0)
#define CCLOGINFO(...) do {} while (0)
#elif COCOS2D_DEBUG == 1
#define CCLOG(...) __CCLOG(__VA_ARGS__)
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
#define CCLOGINFO(...) do {} while (0)
#elif COCOS2D_DEBUG > 1
#define CCLOG(...) __CCLOG(__VA_ARGS__)
#define CCLOGWARN(...) __CCLOGWITHFUNCTION(__VA_ARGS__)
#define CCLOGINFO(...) __CCLOG(__VA_ARGS__)
#endif // COCOS2D_DEBUG
This macro provides for incredible utility which I will want to incorporate in my C++ programs. Writing a useful log statement is as simple as
CCLOG(#"Error in x due to y");
What is even better, is that if the COCOS2D_DEBUG is set to 0, then these statements never see the light of day. There is no overhead for checking a conditional statement to see if logging statements should be used. This is convenient when making the transition from development to production. How could one recreate this same effect in C++?
So does this type of macro belong in a C++ program? Is there a better, more C++ way of doing this?
First, Scott's statement was made at a time when macros were
considerably overused, for historical reasons. While it is
generally true, there are a few cases where macros make sense.
Of of these is logging, because only a macro can automatically
insert __FILE__ and __LINE__. Also, only a macro can
resolve to absolutely nothing (although based on my experience,
this isn't a big deal).
Macros such as you show aren't very frequent in C++. There are
two usual variants for logging:
#define LOG( message ) ... << message ...
which allows messages in the form " x = " << x, and can be
completely suppressed by redefining the macro, and
#define LOG() logFile( __FILE__, __LINE__ )
where logFile returns a wrapper for an std::ostream, which
defines operator<<, and permits such things as:
LOG() << "x = " << x;
Done this way, all of the expressions to the right of LOG()
will always be evaluated, but done correctly, no formatting will
be done unless the log is active.
There are "right" things to use macros for and there are bad uses of macros. Using macros where functions work is a bad idea. Using macros where functions DON'T do the same thing is perfectly good in my book.
I quite often use constructs like this:
#defien my_assert(x) do { if (!x) assert_failed(x, #x, __FILE__, __LINE__); } while(0)
template<typename T>
void assert_failed(T x, const char *x_str, const char *file, int line)
{
std::cerr << "Assertion failed: " << x_str << "(" << x << ") at " << file << ":" << line << std::endl;
std::terminate();
}
Another trick using the stringizing "operator" is something like this:
enum E
{
a,
b,
c,
d
};
struct enum_string
{
E v;
const char *str;
};
#define TO_STR(x) { x, #x }
enum_string enum_to_str[] =
{
TO_STR(a),
TO_STR(b),
TO_STR(c),
TO_STR(d),
};
Saves quite a bit of repeating stuff...
So, yes, it's useful in some cases.
We know that in-line are favorable as they are checked by the compiler and same operation ( like ++x ) does not evaluate more than once when passed as an argument as compared to macros.
But in an interview I was asked the specific advantages or the circumstances when a macro is more favorable to inline in C++.
Does anyone know the answer or can give a thought on this question ?
The only thing I can think of is there are some tricks that you can do with a macro that can't be done with an inline function. Pasting tokens together at compile-time, and that sort of hackery.
Here is a specific situation where macros are not only preferred, they are actually the only way to accomplish something.
If you want to write a logging function which logs not only some message, but the file & line number of where the instance occured, you can either call your function directly, typing in the file & line values (or macros) directly:
LogError("Something Bad!", __FILE__, __LINE__);
...or, if you want it to work automatically, you must rely on a macro (warning: not compiled):
#define LogErrorEx(ERR) (LogError(ERR, __FILE__, __LINE__))
// ...
LogErrorEx("Something Else Bad!");
This cannot be achieved using templates, default parameters, default construction, or any other device in C++.
Sometimes you want to extend the language in ways that aren't possible with any other method.
#include <iostream>
#define CHECK(x) if (x); else std::cerr << "CHECK(" #x ") failed!" << std::endl
int main() {
int x = 053;
CHECK(x == 42);
return 0;
}
This prints CHECK(x == 42) failed!.
In C++ specifically, one usage of MACROs that seem pop up very often (except for the debug print with file and line) is the use of MACROs to fill in a set of standard methods in a class that cannot be inherited from a base class. In some libraries that create custom mechanisms of RTTI, serialization, expression templates, etc., they often rely on a set of static const variables and static methods (and possibly special semantics for some overloaded operators that cannot be inherited) which are almost always the same but need to be added to any class that the user defines within this framework. In these cases, MACROs are often provided such that the user doesn't have to worry about putting all the necessary code (he only has to invoke the MACRO with the require info). For example, if I make a simple RTTI (Run-Time Type Identification) system, I might require that all classes have a TypeID and be dynamically castable:
class Foo : public Bar {
MY_RTTI_REGISTER_CLASS(Foo, Bar, 0xBAADF00D)
};
#define MY_RTTI_REGISTER_CLASS(CLASSNAME,BASECLASS,UNIQUEID) \
public:\
static const int TypeID = UNIQUEID;\
virtual void* CastTo(int aTypeID) {\
if(aTypeID == TypeID)\
return this;\
else\
return BASECLASS::CastTo(aTypeID);\
};
The above could not be done with templates or inheritance, and it makes the user's life easier and avoids code repetition.
I would say that this kind of use of MACROs is by far the most common in C++.
As already said, macros can use preprocessor directives: __FILE__, __LINE__ for instance, but of course #include and #define can also be useful to parameter behaviour:
#ifdef __DEBUG__
# define LOG(s) std:cout << s << std:endl
#else
# define LOG(s)
#endif
Depending wether __DEBUG__ is defined or not (via #define or via compiler options), the LOG macro will be active or not. This is an easy way to have debug info everywhere in your code that can be easily de-activated.
You can also think of changing the way memory is allocated (malloc will be redefined to target a memory pool instead of the standard heap for instance, etc...).
Inline functions are, as the name indicates, restricted to functional tasks, execution of some code.
Macros have a much broader application they may expand e.g to declarations or replace entire language constructs. Some examples (written for C and C++) that can't be done with functions:
typedef struct POD { double a; unsigned b } POD;
#declare POD_INITIALIZER { 1.0, 37u }
POD myPOD = POD_INITIALIZER;
#define DIFFICULT_CASE(X) case (X)+2 :; case (X)+3
#define EASY_CASE(X) case (X)+4 :; case (X)+5
switch (a) {
default: ++a; break;
EASY_CASE('0'): --a; break;
DIFFICULT_CASE('A'): a = helperfunction(a); break;
}
#define PRINT_VALUE(X) \
do { \
char const* _form = #X " has value 0x%lx\n"; \
fprintf(stderr, _form, (unsigned long)(X)); \
} while (false)
In the context of C++, Boost has a lot of more examples that are more involved and more useful.
But because with such macros you are in some sort extending the language (not strictly, the preprocessor is part of it) many people dislike macros, particularly in the C++ community, a bit less in the C community.
In any case, if you use such constructs you should always be very clear in what the should achieve, document well, and fight against the temptation to obfuscate your code.
A macro is just like a text replacement definition.
These essential differences that come into my mind are:
It must not be function-like. I mean it must not necessarily contain some consistent set of brackets for example.
It can be used elsewhere. Like in a class declaration scope or even in the global scope. So it must not be in the scope of another function.
You must use them if you want to perform actions that are impossible to be performed using functions:
initializing complicated tables (makes core more readable)
ease declaration of some special members like event IDs or tag classes (used a lot in MFC IMPLEMENT_DYNAMIC)
squeeze repetitive declarations at the beginning of functions
the already mentioned use of __LINE__, __FILE__, ... for logging
#include <stdio.h>
#define sq(x) x*x
int main()
{
printf("%d", sq(2+1));
printf("%d", sq(2+5));
return 0;
}
The output for this code are 5 and 17. Macros expand textually. Its not like functions.
Explanation for this example:
sq(2+1) = 2+1*2+1 = 2+2+1 = 5
sq(2+5) = 2+5*2+5 = 2+10+5 = 17
I would add two uses:
MIN and MAX, until C++0x, because the return type had to be declared by hand, mixed min and max as inlined functions would have been nightmarish, while a simple macro did it in the blink of an eye.
privacy: you can always undef the macro before exiting your header, you cannot "undeclare" an inline function (or another symbol). This is due to the absence of proper modularity in C and C++ languages.