Is there a way to have a conditional preprocessor in c++ - c++

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.

Related

C++ Stop Preprocessor Macro Expansion

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.

Way to toggle debugging code on and off

I was programming a manchester decoding algorithm for arduino, and I often had to print debug stuff when trying to get things working, but printing to serial and string constants add a lot of overhead. I can't just leave it there in the final binary.
I usually just go through the code removing anything debug related lines.
I'm looking for a way to easily turn it on and off.
The only way I know is this
#if VERBOSE==1
Serial.println();
Serial.print(s);
Serial.print(" ");
Serial.print(t);
Serial.print(" preamble");
#endif
...
#if VERBOSE==1
Serial.println(" SYNC!\n");
#endif
and on top of the file I can just have
#define VERBOSE 0 // 1 to debug
I don't like how much clutter it adds to single liners. I was very tempted to do something very nasty like this. But yeah, evil.
Change every debug output to
verbose("debug message");
then use
#define verbose(x) Serial.print(x) //debug on
or
#define verbose(x) //debug off
There's a C++ feature that allows me to just do this instead of preprocessor?
At the risk of sounding silly: Yes, there is a C++ feature for this, it looks like this:
if (DEBUG)
{
// Your debugging stuff here…
}
If DEBUG is a compile-time constant (I think using a macro is reasonable but not required in this case), the compiler will almost certainly generate no code (not even a branch) for the debugging stuff if debug is false at compile-time.
In my code, I like having several debugging levels. Then I can write things like this:
if (DEBUG_LEVEL >= DEBUG_LEVEL_FINE)
{
// Your debugging stuff here…
}
Again, the compiler will optimize away the entire construct if the condition is false at compile-time.
You can even get more fancy by allowing a two-fold debugging level. A maximum level enabled at compile-time and the actual level used at run-time.
if (MAX_DEBUG >= DEBUG_LEVEL_FINE && Config.getDebugLevel() >= DEBUG_LEVEL_FINE)
{
// Your debugging stuff here…
}
You can #define MAX_DEBUG to the highest level you want to be able to select at run-time. In an all-performance build, you can #define MAX_DEBUG 0 which will make the condition always false and not generate any code at all. (Of course, you cannot select debugging at run-time in this case.)
However, if squeezing out the last instruction is not the most important issue and all your debugging code does is some logging, then the usual pattern lokks like this:
class Logger
{
public:
enum class LoggingLevel { ERROR, WARNING, INFO, … };
void logError(const std::string&) const;
void logWarning(const std::string&) const;
void logInfo(const std::string&) const;
// …
private:
LoggingLevel level_;
};
The various functions then compare the current logging level to the level indicated by the function name and if it is less, immediately return. Except in tight loops, this will probably be the most convenient solution.
And finally, we can combine both worlds by providing inline wrappers for the Logger class.
class Logger
{
public:
enum class LoggingLevel { ERROR, WARNING, INFO, … };
void
logError(const char *const msg) const
{
if (COMPILE_TIME_LOGGING_LEVEL >= LoggingLevel::ERROR)
this->log_(LoggingLevel::ERROR, msg);
}
void
logError(const std::string& msg) const
{
if (COMPILE_TIME_LOGGING_LEVEL >= LoggingLevel::ERROR)
this->log_(LoggingLevel::ERROR, msg.c_str());
}
// …
private:
LoggingLevel level_;
void
log_(LoggingLevel, const char *) const;
};
As long as evaluating the function arguments for your Logger::logError etc calls does not have visible side-effects, chances are good that the compiler will eliminate the call if the conditional in the inline function is false. This is why I have added the overloads that take a raw C-string to optimize the frequent case where the function is called with a string literal. Look at the assembly to be sure.
Personally I wouldn't have a a lot of #ifdef DEBUG scattered around my code:
#ifdef DEBUG
printf("something");
#endif
// some code ...
#ifdef DEBUG
printf("something else");
#endif
rather, I would wrap it in a function:
void DebugPrint(const char const *debugText) // ToDo: make it variadic [1]
{
#ifdef DEBUG
printf(debugText);
#endif
}
DebugPrint("something");
// some code ...
DebugPrint("something else");
If you don't define DEBUG then the macro preprocessor (not the compiler) won't expand that code.
The slight downside of my approach is that, although it makes your cod cleaner, it imposes an extra function call, even if DEBUG is not defined. It is possible that a smart linker will realize that the called function is empty and will remove the function calls, but I wouldn't bank on it.
References:
“Variadic function” in: Wikipedia, The Free Encyclopedia.
I also would suggest to use inline functions which become empty if a flag is set. Why when it is set? Because you usually want to debug always unless you compile a release build.
Because NDEBUG is already used you could use it too to avoid using multiple different flags. The definition of a debug level is also very useful.
One more thing to say: Be careful using functions which are altered by using macros! You could easily violate the One Definition Rule by translating some parts of your code with and some other without debugging disabled.
You might follow the convention of assert(3) and wrap debugging code with
#ifndef NDEBUG
DebugPrint("something");
#endif
See here (on StackOverflow, which would be a better place to ask) for a practical example.
In a more C++ like style, you could consider
ifdef NDEBUG
#define debugout(Out) do{} while(0)
#else
extern bool dodebug;
#define debugout(Out) do {if (dodebug) { \
std::cout << __FILE__ << ":" << __LINE__ \
<< " " << Out << std::endl; \
}} while(0)
#endif
then use debugout("here x=" << x) in your program. YMMV. (you'll set your dodebug flag either thru a gdb command or thru some program argument, perhaps parsed using getopt_long(3), at least on Linux).
PS. Remind that the do{...}while(0) is an old trick to make a robust statement like macro (suitable in every position where a plain statement is, e.g. as the then or else part of an if etc...).
You could also use templates utilizing the constexpr if feature in C++17. you don't have to worry about the preprocessor at all but your declaration and definition have to be in the same place when using templates.

Do pre-processor macros for debug log statements have a place in C++?

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.

Advantage of macro over in-line in C++

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.

Enum declaration inside a scope that is a parameter of a macro

I am trying to create a macro that takes a scope as a parameter.
I know, it is probably not a good thing etc etc.
I was trying this and got the problem that preprocessor looks for commas and parentheses... the problem is with enum.
How would I declare a enum inside a scope that is a parameter of a macro?
when the compiler see the comma between enum itens, it takes it as a separator.
If you are curious to know why I entered into this, is because I need to register my namespaces and classes, for namespaces I need to know when they are closed, so I was thinking to create a macro that initially calls a static function that register the namespace, encapsulate its contents and finally call a static function that removes the namespace from the registry.
With a macro it would be easier for the coder to do this and make sure he doesn't forget to remove the namespace in the end of the bracket.
Thanks,
Joe
EDIT:
I want a macro that accepts a scope as parameters:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
// please, don't take this code seriously, it is just an example so you can understand my question
});
now, if I try:
#define MYMACRO(unkownscope) unknownscope
class MYMACRO({
enum {
anything = 1,
everything = 2
};
});
it won't compile because of the comma inside the enum, because the compiler thinks it is a separator of the macro. It doesn't happen with commas inside parentheses, example:
int a(){
int x = anyfunction(1, 2);
}
would compile normally because the comma is inside a double parentheses.
Sorry for not being able to explain earlier... my english is not that good and the words just keep skipping me =[
Ty for the answers!
Joe
It sounds like you are pushing the preprocessor beyond where it's willing to go. While it's not as elegant, how about breaking your macro in two (one pre- and one post-) and rather then passing a "scope" as parameter, you surround your scope with you pre- and post- macros.
So, if your macro looks something like:
SOMACRO({ ... });
You would instead do something like:
PRESOMACRO();
{ ... };
POSTSOMACRO();
#define SCOPED_STUFF(pre,post) pre; STUFF; post;
#define STUFF enum {a,b,c}
SCOPED_STUFF(a,b)
#undef STUFF
#define STUFF enum {q,r}
SCOPED_STUFF(c,d)
#undef STUFF
You are attempting to replicate RAII with a macro.
#define SCOPE(ns) NamespaceRegistrar _ns_rar(ns);
struct NamespaceRegistrar {
std::string _ns;
NamespaceRegistrar(const std::string& ns) : _ns(ns) { AcquireResource(_ns); }
~NamespaceRegistrar() { ReleaseResource(_ns); }
};
{
SCOPE("Foo")
// stuff
}
I have no idea what you are talking about with regard to enums.
You already noticed what the problem is, an article on boostpro.com sums the problem up.
There are work-arounds, but i'd go for utilizing Boost.Preprocessor.
Without knowing exactly what you're trying to achieve syntactically, something like this might be what you are looking for (edited to PP_SEQ):
#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) }
MAKE_ENUM(foo, (a)(b)(c));