I want to write some code to be compatible with different boost versions, and want to use appropriate functions for the given boost versions. Right now I am trying,
#if BOOST_VERSION>105000
#define boost_sleep boost::this_thread::sleep_for
#define millisectime boost::chrono::milliseconds
#define timed_join try_join_for
#else
#define boost_sleep boost::this_thread::sleep
#define millisectime boost::posix_time::milliseconds
#endif
Which seem to compile fine. I am using it in the code with something like,
// Wait for no reason,
boost_sleep(millisectime(1000));
if( !(workerThread->timed_join(millisectime(1000)) )){
cout << "Not joined on time" << endl;
workerThread->detach();
}
Is there a better/standard way to do this? any suggestions to improve this?
The macro works, but has the problem that you might accidentally replace something other than the function of boost. Maybe one of the third party headers that you include happen to define a variable, or a function or anything with identifier timed_join or millisectime. Perhaps that definition is in an undocumented implementation detail namespace.
Macro replacement for types: A type alias.
typedef boost::
#if BOOST_VERSION>105000
chrono
#else
posix_time
#endif
::milliseconds millisectime;
Macro replacement for functions: A wrapper function.
void boost_sleep(millisectime m) {
return boost::this_thread::sleep
#if BOOST_VERSION>105000
_for
#endif
(m);
}
Wrapping the member function will change the usage slightly
void timed_join(boost_thread_type& t, millisectime m) {
t->
#if BOOST_VERSION>105000
try_join_for
#else
timed_join
#endif
(m);
}
Usage:
timed_join(workerThread, millisectime(1000));
Your definitions are aliases; C++ doesn't need a preprocessor for that.
I.e.
#if BOOST_VERSION>105000
using millisectime = boost::chrono::milliseconds;
void boost_sleep(millisectime t) { boost::this_thread::sleep_for(t); }
#else
...
Related
I am trying to write software that can behave differently based on whether or not a certain component should be simulated in software or execute on real hardware. However, GCC complains that the Scope resolution operator (::) cannot be used in a macro, so my question is: is it possible to define a macro to a static method call?
My goal is to be able to, using another preprocessor define, choose between using all real components (0), using all simulated components (1), or using a mix of real and simulated components (2). This last case is where I am running into this issue. Under this condition, I want to call a function which I am "protecting" by implementing it as a static method. Here is my approach:
#define SIM_CONF 2
#if SIM_CONF == 0
#define IS_HW_SIMULATED(name) false
#define IS_HW_REAL(name) true
#endif
#if SIM_CONF == 1
#define IS_HW_SIMULATED(name) true
#define IS_HW_REAL(name) false
#endif
#if SIM_CONF == 2
#define IS_HW_SIMULATED(name) SimConfig::isSimulated(name)
#define IS_HW_REAL(name) SimConfig::isReal(name)
#endif
class SimConfig
{
public:
static bool isSimulated(const char* szName);
static bool isReal(const char* szName);
};
EDIT: Here's an example of how I use it elsewhere:
void PumpComponent::commandRevs(float revs)
{
#if IS_HW_SIMULATED("PumpComponent")
// do simulation procedure
#else
// do real hardware procedure
#endif
}
When I compile, GNU Make complains:
error: token "::" is not valid in preprocessor expressions
#define IS_HW_SIMULATED(name) SimConfig::isSimulated(name)
Is there some approach where I can protect/encapsulate the isSimulated() and isReal() functions, and still be able to refer to them in preprocessor directives?
Problem is how you use this macro. You have placed it as preprocessor #if argument.
Processor do not understand code and argument of #if must be something what processor can handle, so macros and literals.
SimConfig::isSimulated is a code which in not defined yet. It will be know during compilation process, so after preprocessing is completed.
One way to fix it is simply use if else
void PumpComponent::commandRevs(float revs)
{
if IS_HW_SIMULATED("PumpComponent") {
// do simulation procedure
} else {
// do real hardware procedure
}
}
It is not problem for compiler. it will noticed that this is constant and should remove obsolete code.
Other way to fix it is to abandon macros. You can use templates.
Or enclose macro depended stuff in some class and use macros to alter that class functionality (this way this macros will not spread all over your code).
Don't use #if for this. Just write normal code:
void PumpComponent::commandRevs(float revs)
{
if (IS_HW_SIMULATED("PumpComponent")) {
// do simulation procedure
} else {
// do real hardware procedure
}
}
The compiler will delete one of the branches when SIM_CONF is 0 or 1, since the branch condition is a compile-time constant. It will keep the branches when it's 2.
However, I don't see a reason to have the IS_HW_SIMULATED and IS_HW_REAL macros at all. Looking at the code you posted, it seems you only need one function: SimConfig::isSimulated():
bool SimConfig::isSimulated(const char* szName)
{
#if SIM_CONF == 1
(void)szName; // supress "unused parameter" warning
return true;
#else
// Your normal implementation.
#endif
}
The rest of your code doesn't need to use any macros then:
void PumpComponent::commandRevs(float revs)
{
if (SimConfig::isSimulated("PumpComponent")) {
// do simulation procedure
} else {
// do real hardware procedure
}
}
SimConfig::isReal() doesn't seem to serve any purpose.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I know the basic rules, use inline, enum and const instead of #define, that is not what I'm after with this question. What I want to know is what is considered an acceptable scenario in which you would use a #define macro, and how, in C++.
Please do not post question or links to "define vs const" questions or "preprocessor vs compiler", and I've already gone through Effective C++ by Scott Meyers and I know the advantages of one over the other.
However after hours and hours of surfing the net, I get the feeling #define is treated as some kind of underdog in C++, but I'm sure there must be a case in which it could be acceptable, even desirable, to use it.
To get the ball rolling I guess one scenario I could think of is to create a DEBUG macro that based on it enables prints and whatnot all over the code for debug purposes.
Here are a few scenarios where using #define is a good solution:
Adding diagnostics information while preserving function signature:
#ifdef _DEBUG
#define Log(MSG) Log((MSG), __FILE__, __LINE__);
#endif
Conditional compilation and include guards are also a good example (no example given, as you should understand this :)).
Boilerplate code is another example, but this can easily be abused. A good example of using macros for boilerplate code is the BOOST_AUTO_TEST_CASE macro in Boost.UnitTest (a worse example is the WinAPI macro set that maps Windows APIs to their CHAR or WCHAR macros).
Another good example is providing compiler-specific keywords and settings:
#if (defined _WIN32) && (defined LIB_SHARED)
# ifdef LIB_EXPORTS
# define LIB_EXPORT __declspec(dllexport)
# else
# define LIB_EXPORT __declspec(dllimport)
# endif /* LIB_EXPORTS */
#else
# define LIB_EXPORT extern
#endif /* _WIN32 && LIB_SHARED */
Usage:
// forward declaration of API function:
LIB_EXPORT void MyFunction(int);
The simple setup for debug/release or for crossplatform code. Here is a sample of my program:
void Painter::render()
{
if (m_needsSorting)
{
_sort();
}
for (GameObject* o : m_objects)
{
o->render();
#ifdef _DEBUG
o->renderDebug();
#endif
}
}
and one more for win/ios:
#ifdef _WIN32
#include "EGL/egl.h"
#include "GLES2/gl2.h"
#include <Windows.h>
#ifdef _ANALYZE
#include <vld.h>
#endif
#else // IOS
#import <Availability.h>
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
#import <Foundation/Foundation.h>
#endif
the other thing is for libraries:
#ifdef VECTRY_INLINE
#define vinline inline
#else
#define vinline
#endif
and some useful stuff like this:
#define MakeShared(T) \
class T; \
typedef shared_ptr<T> T##Ptr
Sometimes, you want to generate code without having to repeat the neverending boilerplate, or without having to use another language to do so. From time to time, templates will not be not enough, and you will end up using Boost.Preprocessor to generate your code.
One example where macros are "required" is Boost.TTI (type traits introspection). The underlying mechanism somehow abuses the language to create a couple of powerful metafunctions, but needs great amounts of boilerplate. For example, the macro BOOST_TTI_HAS_MEMBER_FUNCTION generates a matefunction that checks whether a class has a given member function. Doing so requires to create a new class and cannot be short without a macro (examples of non-macro solutions to tackle the problem here).
There are also some times when you will need to use X-macros to generate your code. It is pretty useful to bind things at compile time. I am not sure whether they can be totally replaced or not as of today, but anyway, you can find some really interesting examples of applications here.
To sum up, macros can be a powerful tool to generate code, but they need to be used with caution.
One of the few usefull cases in C++ are include guards:
// A.h
#ifndef _A_H_
#define _A_H_
class A
{ /* ... */ };
#endif /* _A_H_ */
I think when C was introduced then C didn't use to have consts, so #defines were the only way of providing constant values. But later on #define was not much used since consts took the place(or in better words we can say that consts were more readily used). But I would say include guards is still one area where they are used. And they are used since your code is more readable.
Header inclusion guards is one area where you cannot use consts
And example:
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct foo {
int member;
};
#endif /* GRANDFATHER_H */
You may also check Why would someone use #define to define constants?
One more thing to add that #defines don't respect scopes so there is no way to create a class scoped namespacewhereas const variables can be scoped in classes.(I know you know the difference but thought to add it as it is important.)
Also to show one example where #define is used:
static double elapsed()
{ ... }
#define ELAPSED '[' << std::fixed << std::setprecision(2) << elapsed() << "] "
// usage:
for (vector<string>::iterator f = files.begin(); f != files.end(); f++) {
cout << ELAPSED << "reading file: " << *f << '\n';
process_file(*f);
}
I am trying to do something like this
#define VB_S #ifdef VERBOSE
#define VB_E #endif
so that in the code instead of writing
#ifdef VERBOSE
cout << "XYZ" << endl;
#endif
I can write
VB_S
cout << "XYZ" << endl;
VB_E
This gives me a compile time error: Stray '#' in the program.
Can anyone put light on what is the right way to do this
You can't put directives inside macros. (# inside a macro as another signification -- it is the stringizing operator and must be followed by a parameter id -- but the restriction is older than that meaning)
You could do something like this:
#ifdef VERBOSE
#define VB(x) x
#else
#define VB(x) do { } while (false)
#endif
VB(cout << "foo");
Similar to Erik's response:
#ifdef VERBOSE
#define VB(...) __VA_ARGS__
#else
#define VB(...) /* nothing */
#endif
Using a variadic macro has the benefit of allowing commas inside the VB() call. Also, AFAIK, you can remove the do...while.
I prefer the following:
#define VERBOSE 1
// or 0, obviously
if (VERBOSE)
{
// Debug implementation
}
This is a little more readable since VB_S doesn't mean anything to the average user, but if (VERBOSE) does.
How do I implement no-op macro in C++?
#include <iostream>
#ifdef NOOP
#define conditional_noop(x) what goes here?
#else
#define conditional_noop(x) std::cout << (x)
#endif
int main() {
conditional_noop(123);
}
I want this to do nothing when NOOP is defined and print "123", when NOOP is not defined.
While leaving it blank is the obvious option, I'd go with
#define conditional_noop(x) do {} while(0)
This trick is obviously no-op, but forces you to write a semicolon after conditional_noop(123).
As mentioned before - nothing.
Also, there is a misprint in your code.
it should be #else not #elif. if it is #elif it is to be followed by the new condition
#include <iostream>
#ifdef NOOP
#define conditional_noop(x) do {} while(0)
#else
#define conditional_noop(x) std::cout << (x)
#endif
Have fun coding!
EDIT: added the [do] construct for robustness as suggested in another answer.
Defining the macro to be void conveys your intent well.
#ifdef NOOP
#define conditional_noop(x) (void)0
#else
#ifdef NOOP
#define conditional_noop(x)
#elif
nothing!
#ifdef NOOP
static inline void conditional_noop(int x) { }
#else
static inline void conditional_noop(int x) { std::cout << x; }
#endif
Using inline function void enables type checking, even when NOOP isn't defined. So when NOOP isn't defined, you still won't be able to pass a struct to that function, or an undefined variable.
This will eventually prevent you from getting compiler errors when you turn the NOOP flag on.
You can just leave it blank. You don't need to follow the #define with anything.
Like others have said, leave it blank.
A trick you should use is to add (void)0 to the macro, forcing users to add a semicolon after it:
#ifdef NOOP
#define conditional_noop(x) (void)0
#else
#define conditional_noop(x) std::cout << (x); (void)0
#endif
In C++, (void)0 does nothing. This article explains other not-as-good options, as well as the rationale behind them.
As this is a macro, you should also consider a case like
if (other_cond)
conditional_noop(123);
to be on the safe side, you can give an empty statement like
#define conditional_noop(X) {}
for older C sometimes you need to define the empty statment this way (should also get optimized away):
#define conditional_noop(X) do {} while(0)
I think that a combination of the previous variants is a good solution:
#ifdef NOOP
static inline void conditional_noop(int x) do {} while(0)
#else
static inline void conditional_noop(int x) do { std::cout << x; } while(0)
#endif
The good thing is that these two codes differ only inside a block, which means that their behaviour for the outside is completely identical for the parser.
For some reason I need to temporarily disable some macros in a header file and the #undef MACRONAME will make the code compile but it will undef the existing macro.
Is there a way of just disabling it?
I should mention that you do not really know the values of the macros and that I'm looking for a cross compiler solution (should work at least in GCC and MSVC).
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")
Using just the facilities defined by Standard C (C89, C99 or C11), the only 'disable' mechanism is #undef.
The problem is there is no 're-enable' mechanism.
As others have pointed out, if the header file containing the macro definitions is structured so that it does not contain any typedef or enum declarations (these cannot be repeated; function and variable declarations can be repeated), then you could #undef the macro, do what you need without the macro in effect, and then re-include the header, possibly after undefining its protection against reinclusion.
If the macros are not defined in a header, of course, you are stuck until you refactor the code so that they are in a header.
One other trick is available - if the macros are function-like macros and not object-like macros.
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
The function nonsense() is defined fine, despite the macro immediately before it. This is because a macro invocation - for a function-like macro - must be immediately followed by an open parenthesis (give or take white space, possibly including comments). In the function definition line, the token after 'nonsense' is a close parenthesis, so it is not an invocation of the nonsense macro.
Had the macro been an argument-less object-like macro, the trick would not work:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
This code defines a bogus function that's called min and is nonsensical. And there's no protection from the macro.
This is one of the reasons why the standard is careful to define which namespaces are reserved for 'The Implementation'. The Implementation is allowed to define macros for any purpose it desires or needs, of any type (function-like or object-like) it desires or needs, provided those names are reserved to the implementation. If you as a consumer of the services of The Implementation try to use or define a name reserved to the implementation, you must be aware that your code will probably break sooner or later, and that it will be your fault, not the fault of The Implementation.
Macros make my knees go weak, but wouldn't the most universal solution be to restructure your code so that you wouldn't need to reenable the macro again in the same source file? Wouldn't it be possible to extract some code into a separate function and a separate source file where you can undef the offending macro.
The macros come from some header file, so you should have access to their values. You can then do something like
#include <foo.h> // declares macro FOO
// Do things with FOO
#undef FOO
// do things without FOO
#include <foo.h> // reenable FOO
Your header should then be designed along these lines
#ifndef FOO
#define FOO do_something(x,y)
#endif
EDIT:
You may think that it's that easy:
#ifdef macro
#define DISABLED_macro macro
#undef macro
#endif
// do what you want with macro
#ifdef DISABLED_macro
#define macro DISABLED_macro
#endif
But it's not (like the following example demonstrates)!
#include <iostream>
#include <limits>
#include <windows.h>
#ifdef max
#define DISABLED_max max
#undef max
#endif
int main()
{
std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
#ifdef DISABLED_max
#define max DISABLED_max
#endif
std::cout << max(15,3) << std::endl; // error C3861: "max": identifier not found
return 0;
}
Using #undef on the macro and re-including the original header is also not likely to work, because of the header guards.
So what's left is using the push_macro/pop_macro #pragma directives.
#pragma push_macro("MACRO")
#undef MACRO
// do what you want
#pragma pop_macro("MACRO")
There are specific rules for function-like macroses invokation in C/C++ language.
The function-like macroses have to be invoked in the following way:
Macros-name
Left parethesis
One token for each argument separated by commas
Each token in this list can be separared from another by whitespaces (i.e. actual whitespaces and commas)
With one trick you "disable preprocessor mechanism" with breaking rules for function-like macro invokation, but be still within a rules of function calling mechanism...
#include <iostream>
using namespace std;
inline const char* WHAT(){return "Hello from function";}
#define WHAT() "Hello from macro"
int main()
{
cout << (*WHAT)() << "\n"; // use function
cout << (WHAT)() << "\n"; // use function
cout << WHAT () << "\n"; // use macro
return 0;
}