Macro to prevent code processing - c++

So I've a piece of code, which will access a DLL namespace function if it's in Debug mode, and which I'd like to comment out if it's in Release.
#ifdef DEBUG
#define (DEBUG_CODE) abcd::
#else
#define (DEBUG_CODE) <Condition to skip processing>
if (some condition)
(DEBUG_CODE) func_name();
While I'd like the #else to define a comment, I suppose you can't do that because they're skipped by the compiler before any code processing, or preprocessing is performed..
If that is correct, then kindly tell me a way to skip the processing of (DEBUG_CODE) func_name();. There are a lot of places where it is used, and I don't wish to add if(DEBUG) everywhere.
EDIT
The namespace DLL has functions which do not return anything, as well as functions which are expected to return a value, and which might be assigned to an enum.
i.e.
abcd::func_name();
and
int rs = abcd::func_name_2();
and
enum XYZ{ var1 = 0; var2};
XYZ PQR = abcd::func_name3(); //This Enum will prevent me from defining some kind
// 0; as a `#define`
So..multiple scenarios..
Thanks for your help.

You can do this if you change DEBUG_CODE to
#ifdef DEBUG
# define DEBUG_CODE(code) abcd::code;
#else
# define DEBUG_CODE(code) ;
#endif
and then you would call it like this:
if(some_condition) DEBUG_CODE(func_name())
In debug mode this calls your function and in release mode no code is generated.
If you want to be able to assign the return values of these functions to variable or return from them (though I don't think it's a good idea, as I explain in the comments) I would make the macro take what to call in debug mode and what to use in release mode.
#ifdef DEBUG
# define IF_DEBUG_ELSE(debug_code, release_code) abcd::debug_code
#else
# define IF_DEBUG_ELSE(debug_code, release_code) release_code
#endif
This makes it clear at least when you call the macro what's happening.
This can be used like:
return IF_DEBUG_ELSE(check_result(), 0);//0 for success
if(IF_DEBUG_ELSE(check_condition(), true)){}
XYZ xyz = IF_DEBUG_ELSE(get_xyz(), First_XYZ);
and so on like that.

Related

Use of Macro Expansion [duplicate]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
The C preprocessor is justifiably feared and shunned by the C++ community. In-lined functions, consts and templates are usually a safer and superior alternative to a #define.
The following macro:
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
is in no way superior to the type safe:
inline bool succeeded(int hr) { return hr >= 0; }
But macros do have their place, please list the uses you find for macros that you can't do without the preprocessor.
Please put each use-cases in a seperate answer so it can be voted up and if you know of how to achieve one of the answers without the preprosessor point out how in that answer's comments.
As wrappers for debug functions, to automatically pass things like __FILE__, __LINE__, etc:
#ifdef ( DEBUG )
#define M_DebugLog( msg ) std::cout << __FILE__ << ":" << __LINE__ << ": " << msg
#else
#define M_DebugLog( msg )
#endif
Since C++20 the magic type std::source_location can however be used instead of __LINE__ and __FILE__ to implement an analogue as a normal function (template).
Methods must always be complete, compilable code; macros may be code fragments. Thus you can define a foreach macro:
#define foreach(list, index) for(index = 0; index < list.size(); index++)
And use it as thus:
foreach(cookies, i)
printf("Cookie: %s", cookies[i]);
Since C++11, this is superseded by the range-based for loop.
Header file guards necessitate macros.
Are there any other areas that necessitate macros? Not many (if any).
Are there any other situations that benefit from macros? YES!!!
One place I use macros is with very repetitive code. For example, when wrapping C++ code to be used with other interfaces (.NET, COM, Python, etc...), I need to catch different types of exceptions. Here's how I do that:
#define HANDLE_EXCEPTIONS \
catch (::mylib::exception& e) { \
throw gcnew MyDotNetLib::Exception(e); \
} \
catch (::std::exception& e) { \
throw gcnew MyDotNetLib::Exception(e, __LINE__, __FILE__); \
} \
catch (...) { \
throw gcnew MyDotNetLib::UnknownException(__LINE__, __FILE__); \
}
I have to put these catches in every wrapper function. Rather than type out the full catch blocks each time, I just type:
void Foo()
{
try {
::mylib::Foo()
}
HANDLE_EXCEPTIONS
}
This also makes maintenance easier. If I ever have to add a new exception type, there's only one place I need to add it.
There are other useful examples too: many of which include the __FILE__ and __LINE__ preprocessor macros.
Anyway, macros are very useful when used correctly. Macros are not evil -- their misuse is evil.
Mostly:
Include guards
Conditional compilation
Reporting (predefined macros like __LINE__ and __FILE__)
(rarely) Duplicating repetitive code patterns.
In your competitor's code.
Inside conditional compilation, to overcome issues of differences between compilers:
#ifdef WE_ARE_ON_WIN32
#define close(parm1) _close (parm1)
#define rmdir(parm1) _rmdir (parm1)
#define mkdir(parm1, parm2) _mkdir (parm1)
#define access(parm1, parm2) _access(parm1, parm2)
#define create(parm1, parm2) _creat (parm1, parm2)
#define unlink(parm1) _unlink(parm1)
#endif
When you want to make a string out of an expression, the best example for this is assert (#x turns the value of x to a string).
#define ASSERT_THROW(condition) \
if (!(condition)) \
throw std::exception(#condition " is false");
String constants are sometimes better defined as macros since you can do more with string literals than with a const char *.
e.g. String literals can be easily concatenated.
#define BASE_HKEY "Software\\Microsoft\\Internet Explorer\\"
// Now we can concat with other literals
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "Settings", &settings);
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "TypedURLs", &URLs);
If a const char * were used then some sort of string class would have to be used to perform the concatenation at runtime:
const char* BaseHkey = "Software\\Microsoft\\Internet Explorer\\";
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "Settings").c_str(), &settings);
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "TypedURLs").c_str(), &URLs);
Since C++20 it is however possible to implement a string-like class type that can be used as a non-type template parameter type of a user-defined string literal operator which allows such concatenation operations at compile-time without macros.
When you want to change the program flow (return, break and continue) code in a function behaves differently than code that is actually inlined in the function.
#define ASSERT_RETURN(condition, ret_val) \
if (!(condition)) { \
assert(false && #condition); \
return ret_val; }
// should really be in a do { } while(false) but that's another discussion.
The obvious include guards
#ifndef MYHEADER_H
#define MYHEADER_H
...
#endif
Let's say we'll ignore obvious things like header guards.
Sometimes, you want to generate code that needs to be copy/pasted by the precompiler:
#define RAISE_ERROR_STL(p_strMessage) \
do \
{ \
try \
{ \
std::tstringstream strBuffer ; \
strBuffer << p_strMessage ; \
strMessage = strBuffer.str() ; \
raiseSomeAlert(__FILE__, __FUNCSIG__, __LINE__, strBuffer.str().c_str()) \
} \
catch(...){} \
{ \
} \
} \
while(false)
which enables you to code this:
RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;
And can generate messages like:
Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"
Note that mixing templates with macros can lead to even better results (i.e. automatically generating the values side-by-side with their variable names)
Other times, you need the __FILE__ and/or the __LINE__ of some code, to generate debug info, for example. The following is a classic for Visual C++:
#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "
As with the following code:
#pragma message(WRNG "Hello World")
it generates messages like:
C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World
Other times, you need to generate code using the # and ## concatenation operators, like generating getters and setters for a property (this is for quite a limited cases, through).
Other times, you will generate code than won't compile if used through a function, like:
#define MY_TRY try{
#define MY_CATCH } catch(...) {
#define MY_END_TRY }
Which can be used as
MY_TRY
doSomethingDangerous() ;
MY_CATCH
tryToRecoverEvenWithoutMeaningfullInfo() ;
damnThoseMacros() ;
MY_END_TRY
(still, I only saw this kind of code rightly used once)
Last, but not least, the famous boost::foreach !!!
#include <string>
#include <iostream>
#include <boost/foreach.hpp>
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
}
return 0;
}
(Note: code copy/pasted from the boost homepage)
Which is (IMHO) way better than std::for_each.
So, macros are always useful because they are outside the normal compiler rules. But I find that most the time I see one, they are effectively remains of C code never translated into proper C++.
Unit test frameworks for C++ like UnitTest++ pretty much revolve around preprocessor macros. A few lines of unit test code expand into a hierarchy of classes that wouldn't be fun at all to type manually. Without something like UnitTest++ and it's preprocessor magic, I don't know how you'd efficiently write unit tests for C++.
You can't perform short-circuiting of function call arguments using a regular function call. For example:
#define andm(a, b) (a) && (b)
bool andf(bool a, bool b) { return a && b; }
andm(x, y) // short circuits the operator so if x is false, y would not be evaluated
andf(x, y) // y will always be evaluated
To fear the C preprocessor is like to fear the incandescent bulbs just because we get fluorescent bulbs. Yes, the former can be {electricity | programmer time} inefficient. Yes, you can get (literally) burned by them. But they can get the job done if you properly handle it.
When you program embedded systems, C uses to be the only option apart form assembler. After programming on desktop with C++ and then switching to smaller, embedded targets, you learn to stop worrying about “inelegancies” of so many bare C features (macros included) and just trying to figure out the best and safe usage you can get from those features.
Alexander Stepanov says:
When we program in C++ we should not be ashamed of its C heritage, but make
full use of it. The only problems with C++, and even the only problems with C, arise
when they themselves are not consistent with their own logic.
Some very advanced and useful stuff can still be built using preprocessor (macros), which you would never be able to do using the c++ "language constructs" including templates.
Examples:
Making something both a C identifier and a string
Easy way to use variables of enum types as string in C
Boost Preprocessor Metaprogramming
We use the __FILE__ and __LINE__ macros for diagnostic purposes in information rich exception throwing, catching and logging, together with automated log file scanners in our QA infrastructure.
For instance, a throwing macro OUR_OWN_THROW might be used with exception type and constructor parameters for that exception, including a textual description. Like this:
OUR_OWN_THROW(InvalidOperationException, (L"Uninitialized foo!"));
This macro will of course throw the InvalidOperationException exception with the description as constructor parameter, but it'll also write a message to a log file consisting of the file name and line number where the throw occured and its textual description. The thrown exception will get an id, which also gets logged. If the exception is ever caught somewhere else in the code, it will be marked as such and the log file will then indicate that that specific exception has been handled and that it's therefore not likely the cause of any crash that might be logged later on. Unhandled exceptions can be easily picked up by our automated QA infrastructure.
Code repetition.
Have a look to boost preprocessor library, it's a kind of meta-meta-programming. In topic->motivation you can find a good example.
One common use is for detecting the compile environment, for cross-platform development you can write one set of code for linux, say, and another for windows when no cross platform library already exists for your purposes.
So, in a rough example a cross-platform mutex can have
void lock()
{
#ifdef WIN32
EnterCriticalSection(...)
#endif
#ifdef POSIX
pthread_mutex_lock(...)
#endif
}
For functions, they are useful when you want to explicitly ignore type safety. Such as the many examples above and below for doing ASSERT. Of course, like a lot of C/C++ features you can shoot yourself in the foot, but the language gives you the tools and lets you decide what to do.
I occasionally use macros so I can define information in one place, but use it in different ways in different parts of the code. It's only slightly evil :)
For example, in "field_list.h":
/*
* List of fields, names and values.
*/
FIELD(EXAMPLE1, "first example", 10)
FIELD(EXAMPLE2, "second example", 96)
FIELD(ANOTHER, "more stuff", 32)
...
#undef FIELD
Then for a public enum it can be defined to just use the name:
#define FIELD(name, desc, value) FIELD_ ## name,
typedef field_ {
#include "field_list.h"
FIELD_MAX
} field_en;
And in a private init function, all the fields can be used to populate a table with the data:
#define FIELD(name, desc, value) \
table[FIELD_ ## name].desc = desc; \
table[FIELD_ ## name].value = value;
#include "field_list.h"
Something like
void debugAssert(bool val, const char* file, int lineNumber);
#define assert(x) debugAssert(x,__FILE__,__LINE__);
So that you can just for example have
assert(n == true);
and get the source file name and line number of the problem printed out to your log if n is false.
If you use a normal function call such as
void assert(bool val);
instead of the macro, all you can get is your assert function's line number printed to the log, which would be less useful.
#define ARRAY_SIZE(arr) (sizeof arr / sizeof arr[0])
Unlike the 'preferred' template solution discussed in a current thread, you can use it as a constant expression:
char src[23];
int dest[ARRAY_SIZE(src)];
You can use #defines to help with debugging and unit test scenarios. For example, create special logging variants of the memory functions and create a special memlog_preinclude.h:
#define malloc memlog_malloc
#define calloc memlog calloc
#define free memlog_free
Compile you code using:
gcc -Imemlog_preinclude.h ...
An link in your memlog.o to the final image. You now control malloc, etc, perhaps for logging purposes, or to simulate allocation failures for unit tests.
When you are making a decision at compile time over Compiler/OS/Hardware specific behavior.
It allows you to make your interface to Comppiler/OS/Hardware specific features.
#if defined(MY_OS1) && defined(MY_HARDWARE1)
#define MY_ACTION(a,b,c) doSothing_OS1HW1(a,b,c);}
#elif define(MY_OS1) && defined(MY_HARDWARE2)
#define MY_ACTION(a,b,c) doSomthing_OS1HW2(a,b,c);}
#elif define(MY_SUPER_OS)
/* On this hardware it is a null operation */
#define MY_ACTION(a,b,c)
#else
#error "PLEASE DEFINE MY_ACTION() for this Compiler/OS/HArdware configuration"
#endif
Compilers can refuse your request to inline.
Macros will always have their place.
Something I find useful is #define DEBUG for debug tracing -- you can leave it 1 while debugging a problem (or even leave it on during the whole development cycle) then turn it off when it is time to ship.
You can #define constants on the compiler command line using the -D or /D option. This is often useful when cross-compiling the same software for multiple platforms because you can have your makefiles control what constants are defined for each platform.
In my last job, I was working on a virus scanner. To make thing easier for me to debug, I had lots of logging stuck all over the place, but in a high demand app like that, the expense of a function call is just too expensive. So, I came up with this little Macro, that still allowed me to enable the debug logging on a release version at a customers site, without the cost of a function call would check the debug flag and just return without logging anything, or if enabled, would do the logging... The macro was defined as follows:
#define dbgmsg(_FORMAT, ...) if((debugmsg_flag & 0x00000001) || (debugmsg_flag & 0x80000000)) { log_dbgmsg(_FORMAT, __VA_ARGS__); }
Because of the VA_ARGS in the log functions, this was a good case for a macro like this.
Before that, I used a macro in a high security application that needed to tell the user that they didn't have the correct access, and it would tell them what flag they needed.
The Macro(s) defined as:
#define SECURITY_CHECK(lRequiredSecRoles) if(!DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, true)) return
#define SECURITY_CHECK_QUIET(lRequiredSecRoles) (DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, false))
Then, we could just sprinkle the checks all over the UI, and it would tell you which roles were allowed to perform the action you tried to do, if you didn't already have that role. The reason for two of them was to return a value in some places, and return from a void function in others...
SECURITY_CHECK(ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR);
LRESULT CAddPerson1::OnWizardNext()
{
if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_EMPLOYEE) {
SECURITY_CHECK(ROLE_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD ) -1;
} else if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_CONTINGENT) {
SECURITY_CHECK(ROLE_CONTINGENT_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR) -1;
}
...
Anyways, that's how I've used them, and I'm not sure how this could have been helped with templates... Other than that, I try to avoid them, unless REALLY necessary.
I use macros to easily define Exceptions:
DEF_EXCEPTION(RessourceNotFound, "Ressource not found")
where DEF_EXCEPTION is
#define DEF_EXCEPTION(A, B) class A : public exception\
{\
public:\
virtual const char* what() const throw()\
{\
return B;\
};\
}\
If you have a list of fields that get used for a bunch of things, e.g. defining a structure, serializing that structure to/from some binary format, doing database inserts, etc, then you can (recursively!) use the preprocessor to avoid ever repeating your field list.
This is admittedly hideous. But maybe sometimes better than updating a long list of fields in multiple places? I've used this technique exactly once, and it was quite helpful that one time.
Of course the same general idea is used extensively in languages with proper reflection -- just instrospect the class and operate on each field in turn. Doing it in the C preprocessor is fragile, illegible, and not always portable. So I mention it with some trepidation. Nonetheless, here it is...
(EDIT: I see now that this is similar to what #Andrew Johnson said on 9/18; however the idea of recursively including the same file takes the idea a bit further.)
// file foo.h, defines class Foo and various members on it without ever repeating the
// list of fields.
#if defined( FIELD_LIST )
// here's the actual list of fields in the class. If FIELD_LIST is defined, we're at
// the 3rd level of inclusion and somebody wants to actually use the field list. In order
// to do so, they will have defined the macros STRING and INT before including us.
STRING( fooString )
INT( barInt )
#else // defined( FIELD_LIST )
#if !defined(FOO_H)
#define FOO_H
#define DEFINE_STRUCT
// recursively include this same file to define class Foo
#include "foo.h"
#undef DEFINE_STRUCT
#define DEFINE_CLEAR
// recursively include this same file to define method Foo::clear
#include "foo.h"
#undef DEFINE_CLEAR
// etc ... many more interesting examples like serialization
#else // defined(FOO_H)
// from here on, we know that FOO_H was defined, in other words we're at the second level of
// recursive inclusion, and the file is being used to make some particular
// use of the field list, for example defining the class or a single method of it
#if defined( DEFINE_STRUCT )
#define STRING(a) std::string a;
#define INT(a) long a;
class Foo
{
public:
#define FIELD_LIST
// recursively include the same file (for the third time!) to get fields
// This is going to translate into:
// std::string fooString;
// int barInt;
#include "foo.h"
#endif
void clear();
};
#undef STRING
#undef INT
#endif // defined(DEFINE_STRUCT)
#if defined( DEFINE_ZERO )
#define STRING(a) a = "";
#define INT(a) a = 0;
#define FIELD_LIST
void Foo::clear()
{
// recursively include the same file (for the third time!) to get fields.
// This is going to translate into:
// fooString="";
// barInt=0;
#include "foo.h"
#undef STRING
#undef int
}
#endif // defined( DEFINE_ZERO )
// etc...
#endif // end else clause for defined( FOO_H )
#endif // end else clause for defined( FIELD_LIST )
I've used the preprocesser to calculate fixed-point numbers from floating point values used in embedded systems that cannot use floating point in the compiled code. It's handy to have all of your math in Real World Units and not have to think about them in fixed-point.
Example:
// TICKS_PER_UNIT is defined in floating point to allow the conversions to compute during compile-time.
#define TICKS_PER_UNIT 1024.0
// NOTE: The TICKS_PER_x_MS will produce constants in the preprocessor. The (long) cast will
// guarantee there are no floating point values in the embedded code and will produce a warning
// if the constant is larger than the data type being stored to.
// Adding 0.5 sec to the calculation forces rounding instead of truncation.
#define TICKS_PER_1_MS( ms ) (long)( ( ( ms * TICKS_PER_UNIT ) / 1000 ) + 0.5 )
Yet another foreach macros. T: type, c: container, i: iterator
#define foreach(T, c, i) for(T::iterator i=(c).begin(); i!=(c).end(); ++i)
#define foreach_const(T, c, i) for(T::const_iterator i=(c).begin(); i!=(c).end(); ++i)
Usage (concept showing, not real):
void MultiplyEveryElementInList(std::list<int>& ints, int mul)
{
foreach(std::list<int>, ints, i)
(*i) *= mul;
}
int GetSumOfList(const std::list<int>& ints)
{
int ret = 0;
foreach_const(std::list<int>, ints, i)
ret += *i;
return ret;
}
Better implementations available: Google "BOOST_FOREACH"
Good articles available: Conditional Love: FOREACH Redux (Eric Niebler) http://www.artima.com/cppsource/foreach.html
Maybe the greates usage of macros is in platform-independent development.
Think about cases of type inconsistency - with macros, you can simply use different header files -- like:
--WIN_TYPES.H
typedef ...some struct
--POSIX_TYPES.h
typedef ...some another struct
--program.h
#ifdef WIN32
#define TYPES_H "WINTYPES.H"
#else
#define TYPES_H "POSIX_TYPES.H"
#endif
#include TYPES_H
Much readable than implementing it in other ways, to my opinion.

c++ force compiler to opt out some piece of code

I have a piece of code:
// some code, which only do sanity check
expensive checks
// sanity check end
Now how do I tell the compiler to force it to opt out
this piece? Basically it means when I compile with -O2 or
O3, I don't want it to be there...
Thanks!
You can accomplish this with a constant and a single if/def pair. This allows the code to still be compiled and checked for errors but omitted during optimization. This can prevent changes that might break the check code from going undetected.
#if defined(USE_EXPENSIVE_CHECKS) || defined(DEBUG)
#define USE_EXPENSIVE_CHECKS_VALUE true
#else
#define USE_EXPENSIVE_CHECKS_VALUE false
#endif
namespace {
const bool useExpensiveChecks = USE_EXPENSIVE_CHECKS_VALUE;
};
void function()
{
if(useExpensiveChecks == true)
{
// expensive checks
}
}
Instead of relying on the compiler to optimize the code out, you could pass the compiler an additional symbol definition only when you want the code to run:
// some code, which only do sanity check
#ifdef my_symbol
expensive checks
#endif
// sanity check end
Using macros and conditionals in the preprocessor is really the only way to avoid code being generated by the compiler.
So, here's how I would do it:
#ifdef NEED_EXPENSIVE_CHECKS
inline expensive_checking(params...)
{
... do expensive checking here ...
}
#else
inline expensive_checking(params...)
{
}
#endif
Then just call:
some code
expensive_checking(some_parameters...)
some other code
An empty inlined function will result in "no code" in any decent, modern compiler. Use -DNEED_EXPENSIVE_CHECKS in your debug build settings, and don't use that in release build.
I have also been known to use a combination of macro and function, such as this:
#ifdef NEED_EXPENSIVE_CHECKS
#define EXPENSIVE_CHECKS(stuff...) expensive_checks(__FILE__, __LINE__, stuff...)
inline expensive_checks(const char *file, int line, stuff ...)
{
if (some_checking)
{
cerr << "Error, some_checking failed at " << file << ":" << line << endl;
}
}
#else
#define EXPENSIVE_CHECKS(stuff...)
#endif
Now, you get information on which file and what line when something fails, which can be very useful if the checks are made in many places (and you can use __function__ or __pretty_function__ to get the function name as well, if you wish).
Obviously, the assert() macro will essentially do what my macro solution does, except it usually doesn't provide the filename and line-number.
Move your checks into a different function, then import cassert and write assert(expensive_check()). When you want to disable the checks, use #define NDEBUG before the inclusion of cassert.

Simple ways to disable parts of code

This isn't a typical question to solve a specific problem, it's rather a brain exercise, but I wonder if anyone has a solution.
In development we often need to disable or switch some parts of code to check different approaches. To do this we use comments or #defines, but my favorite is:
//*
[code here]
//*/
Now when you remove just the first slash the code will become commented-out.
The question: is there any way to implement similar if-else code switch? I tried to find it but I always had some problem and couldn't find a working solution.
And maybe do you know any similar tricks?
Wrapping the code with #if 0 does the trick but then you still need to edit the code to enable/disable it. That's not much better than just using the comment block.
Note that you can also use a defined preprocessor constant:
#ifdef ENABLE_TESTS
// code that you want to run ONLY during tests
#endif
Now when building the code, you can selectively define/un-define this constant in your build process - IDE/makefile/build script/command-line - without needing to edit the code:
$ gcc -DENABLE_TESTS source.c
I've added this answer to counter-balance all of the early #if 0 answers, but this construct from the accepted answer is the best answer to the specific question: /**/ foo(); /*/ bar(); /**/. Please use such comment tricks sparingly.
#if 0
...disabled code here
#endif
I'm not sure I should post this because it's not something I think is 'good code', but I'll admit to having used the following technique as a quick-n-dirty way to be able to quickly switch between two small snippets of code when I'm just checking something out:
// in the following , foo() is active:
/**/ foo(); /*/ bar(); /**/
Now just remove one of the asterisks at the front:
// now bar() is active:
/*/ foo(); /*/ bar(); /**/
Of course, this should never make it past the "just checking things out" phase...
Preprocessor if-else also works
#if 1
// ... enabled if 1
#else
// ... enabled if 0
#endif
Use some preprocessor logic to help you out here:
#if 0
//code goes here
#endif
Enjoy
Sometimes I use the below trick to switch between two lazy comments.
//* <-- remove the first slash
[code block 1]
/*/
[code block 2]
//*/
Well, if the code that needed to be disabled once or twice before finalizing, I prefer to use hotkeys provided by IDE to comment that code out, and later comment in. Yes, I need to select the code block first, but I prefer not to include one more debugging variable/preprocessor directive/if statement every time I need to disable a part of code. This happens to be most of the time.
If, on the other hand, I need to repeatedly switch between 2 code blocks to find the right thing, then I use a if (0) / if (1) to disable/enable code block.
[code block 1]
Later
if (0)
{
[code block 1]
}
else
{
[code block 2]
}
If you're doing checks at compile time, you can use Gigi's answer, which will conditionally not compile sections of code. Note that the preprocessor has no knowledge of variables, or sizeof, or other things handled by the compiler (so using something like 4 == sizeof(int) will not fly)
If you want to compile in little bits of debugging code that should not ever get run, you can use regular conditional statements, like such
bool debugging = false;
// banana banana banana
if (debugging)
{
// do a bunch of stuff here
}
You can then use a debugger to access the skipped section by assigning debugging to true.
Macro is the way to do this..
#define COMPILE
#ifdef COMPILE
//code to comment begins
cout<<"ha ha ha"<<endl;
//code to comment ends
#endif
To disable the code, just comment out #define compile line
Synchronously switching on/off chunks of code scattered across the program is sometimes a need too.
Inspired by this earlier post by Graham I cooked up something like this:
void doNothing(){}
#define DO_IF(flag, code) flag ? code : doNothing();
This can be for instance used as follows:
DO_IF(collectStats, recordStats());
DO_IF(collectStats, store(pullStat()));
An that is even better:
#define DO_IF(flag,code) if( flag ) { code; }
1 ? foo() : bar();
This executes foo(). Change the 1 to a 0 to execute bar() instead.
Unlike the suggestions involving preprocessor directives or comments, both possible branches are compiled, so you get the full benefit of the compiler's syntax checking.
Sometimes i use this approach to just not overbloat the code by infinite sequence of if-endif definitions.
debug.hpp
#ifdef _DEBUG
#define IF_DEBUG(x) if(x)
#else
#define IF_DEBUG(x) if(false)
#endif
example.cpp
#include "debug.hpp"
int a,b, ... ,z;
...
IF_DEBUG(... regular_expression_here_with_a_b_z ...) {
// set of asserts
assert(... a ...);
assert(... b ...);
...
assert(... z ...);
}
This is not always effective, because compiler may warn you about unused variables has used inside such disabled blocks of code. But at least it is better readable and unused variable warnings can be suppressed for example like this:
IF_DEBUG(... regular_expression_here_with_a_b_z ...) {
// set of asserts
assert(... a ...);
assert(... b ...);
...
assert(... z ...);
}
else {
(void)a;
(void)b;
....
(void)z;
}
It is not always a good idea, but at least helps to reorganize the code.
the following logic should contain the simplest approach
if(isMode1)
{
//Code for mode1
}
else
{
//Code for other modes
}
although I think the correct way is to use PreProcessor Directives
In my code, I like to do this in my main.cpp file:
#define CRAZY_EXPERIMENT
#ifdef TEST
#include "Test.h"
#elif ANOTHER_TEST
#include "AnotherTest.h"
#elif CRAZY_EXPERIMENT
#include "CrazyExperiment.h"
#else
int main(int argc, int * argv[]){
runTheProgramLikeNormal();
}
#endif
The header files you see all contain their own main(). There is only ever one main() function in the program based on what is defined in the first #define there. If the statement is omitted entirely, it defaults to the canonical main() function you see written.
This makes it easy to write tests for my program that only focus on one or two components by themselves. And the best part is that the test headers are neatly quarantined from my code, so no test code gets left in (or even linked in) by mistake.

What use cases necessitate #define without a token-string?

I have encountered the #define pre-processor directive before while learning C, and then also encountered it in some code I read. But apart from using it to definite substitutions for constants and to define macros, I've not really understook the special case where it is used without a "body" or token-string.
Take for example this line:
#define OCSTR(X)
Just like that! What could be the use of this or better, when is this use of #define necessary?
This is used in two cases. The first and most frequent involves
conditional compilation:
#ifndef XYZ
#define XYZ
// ...
#endif
You've surely used this yourself for include guards, but it can also be
used for things like system dependencies:
#ifdef WIN32
// Windows specific code here...
#endif
(In this case, WIN32 is more likely defined on the command line, but it
could also be defined in a "config.hpp" file.) This would normally
only involve object-like macros (without an argument list or
parentheses).
The second would be a result of conditional compilation. Something
like:
#ifdef DEBUG
#define TEST(X) text(X)
#else
#define TEST(X)
#endif
That allows writing things like:
TEST(X);
which will call the function if DEBUG is defined, and do nothing if it
isn't.
Such macro usually appears in pair and inside conditional #ifdef as:
#ifdef _DEBUG
#define OCSTR(X)
#else
#define OCSTR(X) SOME_TOKENS_HERE
#endif
Another example,
#ifdef __cplusplus
#define NAMESPACE_BEGIN(X) namespace X {
#define NAMESPACE_END }
#else
#define NAMESPACE_BEGIN(X)
#define NAMESPACE_END
#endif
One odd case that I recently dug up to answer a question turned out to be simply commentary in nature. The code in question looked like:
void CLASS functionName(){
//
//
//
}
I discovered it was just an empty #define, which the author had chosen to document that the function accessed global variables in the project:
C++ syntax: void CLASS functionName()?
So not really that different from if it said /* CLASS */, except not allowing typos like /* CLAAS */...some other small benefits perhaps (?)
I agree with every answer, but I'd like to point out a small trivial thing.
Being a C purist I've grown up with the assertion that EACH AND EVERY #define should be an expression, so, even if it's common practice using:
#define WHATEVER
and test it with
#ifdef WHATEVER
I think it's always better writing:
#define WHATEVER (1)
also #debug macros shall be expressions:
#define DEBUG (xxx) (whatever you want for debugging, value)
In this way, you are completely safe from misuse of #macros and prevents nasty problems (especially in a 10 million line C project)
This can be used when you may want to silent some function. For example in debug mode you want to print some debug statements and in production code you want to omit them:
#ifdef DEBUG
#define PRINT(X) printf("%s", X)
#else
#define PRINT(X) // <----- silently removed
#endif
Usage:
void foo ()
{
PRINT("foo() starts\n");
...
}
#define macros are simply replaced, literally, by their replacement text during preprocessing. If there is no replacement text, then ... they're replaced by nothing! So this source code:
#define FOO(x)
print(FOO(hello world));
will be preprocessed into just this:
print();
This can be useful to get rid of things you don't want, like, say, assert(). It's mainly useful in conditional situations, where under some conditions there's a non-empty body, though.
As you can see in the above responses, it can be useful when debugging your code.
#ifdef DEBUG
#define debug(msg) fputs(__FILE__ ":" (__LINE__) " - " msg, stderr)
#else
#define debug(msg)
#endif
So, when you are debugging, the function will print the line number and file name so you know if there is an error. And if you are not debugging, it will just produce no output
There are many uses for such a thing.
For example, one is for the macro to have different behavior in different builds. For example, if you want debug messages, you could have something like this:
#ifdef _DEBUG
#define DEBUG_LOG(X, ...) however_you_want_to_print_it
#else
#define DEBUG_LOG(X, ...) // nothing
#endif
Another use could be to customize your header file based on your system. This is from my mesa-implemented OpenGL header in linux:
#if !defined(OPENSTEP) && (defined(__WIN32__) && !defined(__CYGWIN__))
# if defined(__MINGW32__) && defined(GL_NO_STDCALL) || defined(UNDER_CE) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */
# define GLAPIENTRY
# else
# define GLAPIENTRY __stdcall
# endif
#elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */
# define GLAPIENTRY __stdcall
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
# define GLAPIENTRY
#endif /* WIN32 && !CYGWIN */
#ifndef GLAPIENTRY
#define GLAPIENTRY
#endif
And used in header declarations like:
GLAPI void GLAPIENTRY glClearIndex( GLfloat c );
GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
GLAPI void GLAPIENTRY glClear( GLbitfield mask );
...
(I removed the part for GLAPI)
So you get the picture, a macro that is used in some cases and not used in other cases could be defined to something on those cases and nothing to those other cases.
Other cases could be as follows:
If the macro doesn't take parameters, it could be just to declare some case. A famous example is to guard header files. Another example would be something like this
#define USING_SOME_LIB
and later could be used like this:
#ifdef USING_SOME_LIB
...
#else
...
#endif
Could be that the macro was used at some stage to do something (for example log), but then on release the owner decided the log is not useful anymore and simply removed the contents of the macro so it becomes empty. This is not recommended though, use the method I mentioned in the very beginning of the answer.
Finally, it could be there just for more explanation, for example you can say
#define DONT_CALL_IF_LIB_NOT_INITIALIZED
and you write functions like:
void init(void);
void do_something(int x) DONT_CALL_IF_LIB_NOT_INITIALIZED;
Although this last case is a bit absurd, but it would make sense in such a case:
#define IN
#define OUT
void function(IN char *a, OUT char *b);

When are C++ macros beneficial? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
The C preprocessor is justifiably feared and shunned by the C++ community. In-lined functions, consts and templates are usually a safer and superior alternative to a #define.
The following macro:
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
is in no way superior to the type safe:
inline bool succeeded(int hr) { return hr >= 0; }
But macros do have their place, please list the uses you find for macros that you can't do without the preprocessor.
Please put each use-cases in a seperate answer so it can be voted up and if you know of how to achieve one of the answers without the preprosessor point out how in that answer's comments.
As wrappers for debug functions, to automatically pass things like __FILE__, __LINE__, etc:
#ifdef ( DEBUG )
#define M_DebugLog( msg ) std::cout << __FILE__ << ":" << __LINE__ << ": " << msg
#else
#define M_DebugLog( msg )
#endif
Since C++20 the magic type std::source_location can however be used instead of __LINE__ and __FILE__ to implement an analogue as a normal function (template).
Methods must always be complete, compilable code; macros may be code fragments. Thus you can define a foreach macro:
#define foreach(list, index) for(index = 0; index < list.size(); index++)
And use it as thus:
foreach(cookies, i)
printf("Cookie: %s", cookies[i]);
Since C++11, this is superseded by the range-based for loop.
Header file guards necessitate macros.
Are there any other areas that necessitate macros? Not many (if any).
Are there any other situations that benefit from macros? YES!!!
One place I use macros is with very repetitive code. For example, when wrapping C++ code to be used with other interfaces (.NET, COM, Python, etc...), I need to catch different types of exceptions. Here's how I do that:
#define HANDLE_EXCEPTIONS \
catch (::mylib::exception& e) { \
throw gcnew MyDotNetLib::Exception(e); \
} \
catch (::std::exception& e) { \
throw gcnew MyDotNetLib::Exception(e, __LINE__, __FILE__); \
} \
catch (...) { \
throw gcnew MyDotNetLib::UnknownException(__LINE__, __FILE__); \
}
I have to put these catches in every wrapper function. Rather than type out the full catch blocks each time, I just type:
void Foo()
{
try {
::mylib::Foo()
}
HANDLE_EXCEPTIONS
}
This also makes maintenance easier. If I ever have to add a new exception type, there's only one place I need to add it.
There are other useful examples too: many of which include the __FILE__ and __LINE__ preprocessor macros.
Anyway, macros are very useful when used correctly. Macros are not evil -- their misuse is evil.
Mostly:
Include guards
Conditional compilation
Reporting (predefined macros like __LINE__ and __FILE__)
(rarely) Duplicating repetitive code patterns.
In your competitor's code.
Inside conditional compilation, to overcome issues of differences between compilers:
#ifdef WE_ARE_ON_WIN32
#define close(parm1) _close (parm1)
#define rmdir(parm1) _rmdir (parm1)
#define mkdir(parm1, parm2) _mkdir (parm1)
#define access(parm1, parm2) _access(parm1, parm2)
#define create(parm1, parm2) _creat (parm1, parm2)
#define unlink(parm1) _unlink(parm1)
#endif
When you want to make a string out of an expression, the best example for this is assert (#x turns the value of x to a string).
#define ASSERT_THROW(condition) \
if (!(condition)) \
throw std::exception(#condition " is false");
String constants are sometimes better defined as macros since you can do more with string literals than with a const char *.
e.g. String literals can be easily concatenated.
#define BASE_HKEY "Software\\Microsoft\\Internet Explorer\\"
// Now we can concat with other literals
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "Settings", &settings);
RegOpenKey(HKEY_CURRENT_USER, BASE_HKEY "TypedURLs", &URLs);
If a const char * were used then some sort of string class would have to be used to perform the concatenation at runtime:
const char* BaseHkey = "Software\\Microsoft\\Internet Explorer\\";
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "Settings").c_str(), &settings);
RegOpenKey(HKEY_CURRENT_USER, (string(BaseHkey) + "TypedURLs").c_str(), &URLs);
Since C++20 it is however possible to implement a string-like class type that can be used as a non-type template parameter type of a user-defined string literal operator which allows such concatenation operations at compile-time without macros.
When you want to change the program flow (return, break and continue) code in a function behaves differently than code that is actually inlined in the function.
#define ASSERT_RETURN(condition, ret_val) \
if (!(condition)) { \
assert(false && #condition); \
return ret_val; }
// should really be in a do { } while(false) but that's another discussion.
The obvious include guards
#ifndef MYHEADER_H
#define MYHEADER_H
...
#endif
Let's say we'll ignore obvious things like header guards.
Sometimes, you want to generate code that needs to be copy/pasted by the precompiler:
#define RAISE_ERROR_STL(p_strMessage) \
do \
{ \
try \
{ \
std::tstringstream strBuffer ; \
strBuffer << p_strMessage ; \
strMessage = strBuffer.str() ; \
raiseSomeAlert(__FILE__, __FUNCSIG__, __LINE__, strBuffer.str().c_str()) \
} \
catch(...){} \
{ \
} \
} \
while(false)
which enables you to code this:
RAISE_ERROR_STL("Hello... The following values " << i << " and " << j << " are wrong") ;
And can generate messages like:
Error Raised:
====================================
File : MyFile.cpp, line 225
Function : MyFunction(int, double)
Message : "Hello... The following values 23 and 12 are wrong"
Note that mixing templates with macros can lead to even better results (i.e. automatically generating the values side-by-side with their variable names)
Other times, you need the __FILE__ and/or the __LINE__ of some code, to generate debug info, for example. The following is a classic for Visual C++:
#define WRNG_PRIVATE_STR2(z) #z
#define WRNG_PRIVATE_STR1(x) WRNG_PRIVATE_STR2(x)
#define WRNG __FILE__ "("WRNG_PRIVATE_STR1(__LINE__)") : ------------ : "
As with the following code:
#pragma message(WRNG "Hello World")
it generates messages like:
C:\my_project\my_cpp_file.cpp (225) : ------------ Hello World
Other times, you need to generate code using the # and ## concatenation operators, like generating getters and setters for a property (this is for quite a limited cases, through).
Other times, you will generate code than won't compile if used through a function, like:
#define MY_TRY try{
#define MY_CATCH } catch(...) {
#define MY_END_TRY }
Which can be used as
MY_TRY
doSomethingDangerous() ;
MY_CATCH
tryToRecoverEvenWithoutMeaningfullInfo() ;
damnThoseMacros() ;
MY_END_TRY
(still, I only saw this kind of code rightly used once)
Last, but not least, the famous boost::foreach !!!
#include <string>
#include <iostream>
#include <boost/foreach.hpp>
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
}
return 0;
}
(Note: code copy/pasted from the boost homepage)
Which is (IMHO) way better than std::for_each.
So, macros are always useful because they are outside the normal compiler rules. But I find that most the time I see one, they are effectively remains of C code never translated into proper C++.
Unit test frameworks for C++ like UnitTest++ pretty much revolve around preprocessor macros. A few lines of unit test code expand into a hierarchy of classes that wouldn't be fun at all to type manually. Without something like UnitTest++ and it's preprocessor magic, I don't know how you'd efficiently write unit tests for C++.
You can't perform short-circuiting of function call arguments using a regular function call. For example:
#define andm(a, b) (a) && (b)
bool andf(bool a, bool b) { return a && b; }
andm(x, y) // short circuits the operator so if x is false, y would not be evaluated
andf(x, y) // y will always be evaluated
To fear the C preprocessor is like to fear the incandescent bulbs just because we get fluorescent bulbs. Yes, the former can be {electricity | programmer time} inefficient. Yes, you can get (literally) burned by them. But they can get the job done if you properly handle it.
When you program embedded systems, C uses to be the only option apart form assembler. After programming on desktop with C++ and then switching to smaller, embedded targets, you learn to stop worrying about “inelegancies” of so many bare C features (macros included) and just trying to figure out the best and safe usage you can get from those features.
Alexander Stepanov says:
When we program in C++ we should not be ashamed of its C heritage, but make
full use of it. The only problems with C++, and even the only problems with C, arise
when they themselves are not consistent with their own logic.
Some very advanced and useful stuff can still be built using preprocessor (macros), which you would never be able to do using the c++ "language constructs" including templates.
Examples:
Making something both a C identifier and a string
Easy way to use variables of enum types as string in C
Boost Preprocessor Metaprogramming
We use the __FILE__ and __LINE__ macros for diagnostic purposes in information rich exception throwing, catching and logging, together with automated log file scanners in our QA infrastructure.
For instance, a throwing macro OUR_OWN_THROW might be used with exception type and constructor parameters for that exception, including a textual description. Like this:
OUR_OWN_THROW(InvalidOperationException, (L"Uninitialized foo!"));
This macro will of course throw the InvalidOperationException exception with the description as constructor parameter, but it'll also write a message to a log file consisting of the file name and line number where the throw occured and its textual description. The thrown exception will get an id, which also gets logged. If the exception is ever caught somewhere else in the code, it will be marked as such and the log file will then indicate that that specific exception has been handled and that it's therefore not likely the cause of any crash that might be logged later on. Unhandled exceptions can be easily picked up by our automated QA infrastructure.
Code repetition.
Have a look to boost preprocessor library, it's a kind of meta-meta-programming. In topic->motivation you can find a good example.
One common use is for detecting the compile environment, for cross-platform development you can write one set of code for linux, say, and another for windows when no cross platform library already exists for your purposes.
So, in a rough example a cross-platform mutex can have
void lock()
{
#ifdef WIN32
EnterCriticalSection(...)
#endif
#ifdef POSIX
pthread_mutex_lock(...)
#endif
}
For functions, they are useful when you want to explicitly ignore type safety. Such as the many examples above and below for doing ASSERT. Of course, like a lot of C/C++ features you can shoot yourself in the foot, but the language gives you the tools and lets you decide what to do.
I occasionally use macros so I can define information in one place, but use it in different ways in different parts of the code. It's only slightly evil :)
For example, in "field_list.h":
/*
* List of fields, names and values.
*/
FIELD(EXAMPLE1, "first example", 10)
FIELD(EXAMPLE2, "second example", 96)
FIELD(ANOTHER, "more stuff", 32)
...
#undef FIELD
Then for a public enum it can be defined to just use the name:
#define FIELD(name, desc, value) FIELD_ ## name,
typedef field_ {
#include "field_list.h"
FIELD_MAX
} field_en;
And in a private init function, all the fields can be used to populate a table with the data:
#define FIELD(name, desc, value) \
table[FIELD_ ## name].desc = desc; \
table[FIELD_ ## name].value = value;
#include "field_list.h"
Something like
void debugAssert(bool val, const char* file, int lineNumber);
#define assert(x) debugAssert(x,__FILE__,__LINE__);
So that you can just for example have
assert(n == true);
and get the source file name and line number of the problem printed out to your log if n is false.
If you use a normal function call such as
void assert(bool val);
instead of the macro, all you can get is your assert function's line number printed to the log, which would be less useful.
#define ARRAY_SIZE(arr) (sizeof arr / sizeof arr[0])
Unlike the 'preferred' template solution discussed in a current thread, you can use it as a constant expression:
char src[23];
int dest[ARRAY_SIZE(src)];
You can use #defines to help with debugging and unit test scenarios. For example, create special logging variants of the memory functions and create a special memlog_preinclude.h:
#define malloc memlog_malloc
#define calloc memlog calloc
#define free memlog_free
Compile you code using:
gcc -Imemlog_preinclude.h ...
An link in your memlog.o to the final image. You now control malloc, etc, perhaps for logging purposes, or to simulate allocation failures for unit tests.
When you are making a decision at compile time over Compiler/OS/Hardware specific behavior.
It allows you to make your interface to Comppiler/OS/Hardware specific features.
#if defined(MY_OS1) && defined(MY_HARDWARE1)
#define MY_ACTION(a,b,c) doSothing_OS1HW1(a,b,c);}
#elif define(MY_OS1) && defined(MY_HARDWARE2)
#define MY_ACTION(a,b,c) doSomthing_OS1HW2(a,b,c);}
#elif define(MY_SUPER_OS)
/* On this hardware it is a null operation */
#define MY_ACTION(a,b,c)
#else
#error "PLEASE DEFINE MY_ACTION() for this Compiler/OS/HArdware configuration"
#endif
Compilers can refuse your request to inline.
Macros will always have their place.
Something I find useful is #define DEBUG for debug tracing -- you can leave it 1 while debugging a problem (or even leave it on during the whole development cycle) then turn it off when it is time to ship.
You can #define constants on the compiler command line using the -D or /D option. This is often useful when cross-compiling the same software for multiple platforms because you can have your makefiles control what constants are defined for each platform.
In my last job, I was working on a virus scanner. To make thing easier for me to debug, I had lots of logging stuck all over the place, but in a high demand app like that, the expense of a function call is just too expensive. So, I came up with this little Macro, that still allowed me to enable the debug logging on a release version at a customers site, without the cost of a function call would check the debug flag and just return without logging anything, or if enabled, would do the logging... The macro was defined as follows:
#define dbgmsg(_FORMAT, ...) if((debugmsg_flag & 0x00000001) || (debugmsg_flag & 0x80000000)) { log_dbgmsg(_FORMAT, __VA_ARGS__); }
Because of the VA_ARGS in the log functions, this was a good case for a macro like this.
Before that, I used a macro in a high security application that needed to tell the user that they didn't have the correct access, and it would tell them what flag they needed.
The Macro(s) defined as:
#define SECURITY_CHECK(lRequiredSecRoles) if(!DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, true)) return
#define SECURITY_CHECK_QUIET(lRequiredSecRoles) (DoSecurityCheck(lRequiredSecRoles, #lRequiredSecRoles, false))
Then, we could just sprinkle the checks all over the UI, and it would tell you which roles were allowed to perform the action you tried to do, if you didn't already have that role. The reason for two of them was to return a value in some places, and return from a void function in others...
SECURITY_CHECK(ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR);
LRESULT CAddPerson1::OnWizardNext()
{
if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_EMPLOYEE) {
SECURITY_CHECK(ROLE_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD ) -1;
} else if(m_Role.GetItemData(m_Role.GetCurSel()) == parent->ROLE_CONTINGENT) {
SECURITY_CHECK(ROLE_CONTINGENT_WORKER_ADMINISTRATOR | ROLE_BUSINESS_INFORMATION_STEWARD | ROLE_WORKER_ADMINISTRATOR) -1;
}
...
Anyways, that's how I've used them, and I'm not sure how this could have been helped with templates... Other than that, I try to avoid them, unless REALLY necessary.
I use macros to easily define Exceptions:
DEF_EXCEPTION(RessourceNotFound, "Ressource not found")
where DEF_EXCEPTION is
#define DEF_EXCEPTION(A, B) class A : public exception\
{\
public:\
virtual const char* what() const throw()\
{\
return B;\
};\
}\
If you have a list of fields that get used for a bunch of things, e.g. defining a structure, serializing that structure to/from some binary format, doing database inserts, etc, then you can (recursively!) use the preprocessor to avoid ever repeating your field list.
This is admittedly hideous. But maybe sometimes better than updating a long list of fields in multiple places? I've used this technique exactly once, and it was quite helpful that one time.
Of course the same general idea is used extensively in languages with proper reflection -- just instrospect the class and operate on each field in turn. Doing it in the C preprocessor is fragile, illegible, and not always portable. So I mention it with some trepidation. Nonetheless, here it is...
(EDIT: I see now that this is similar to what #Andrew Johnson said on 9/18; however the idea of recursively including the same file takes the idea a bit further.)
// file foo.h, defines class Foo and various members on it without ever repeating the
// list of fields.
#if defined( FIELD_LIST )
// here's the actual list of fields in the class. If FIELD_LIST is defined, we're at
// the 3rd level of inclusion and somebody wants to actually use the field list. In order
// to do so, they will have defined the macros STRING and INT before including us.
STRING( fooString )
INT( barInt )
#else // defined( FIELD_LIST )
#if !defined(FOO_H)
#define FOO_H
#define DEFINE_STRUCT
// recursively include this same file to define class Foo
#include "foo.h"
#undef DEFINE_STRUCT
#define DEFINE_CLEAR
// recursively include this same file to define method Foo::clear
#include "foo.h"
#undef DEFINE_CLEAR
// etc ... many more interesting examples like serialization
#else // defined(FOO_H)
// from here on, we know that FOO_H was defined, in other words we're at the second level of
// recursive inclusion, and the file is being used to make some particular
// use of the field list, for example defining the class or a single method of it
#if defined( DEFINE_STRUCT )
#define STRING(a) std::string a;
#define INT(a) long a;
class Foo
{
public:
#define FIELD_LIST
// recursively include the same file (for the third time!) to get fields
// This is going to translate into:
// std::string fooString;
// int barInt;
#include "foo.h"
#endif
void clear();
};
#undef STRING
#undef INT
#endif // defined(DEFINE_STRUCT)
#if defined( DEFINE_ZERO )
#define STRING(a) a = "";
#define INT(a) a = 0;
#define FIELD_LIST
void Foo::clear()
{
// recursively include the same file (for the third time!) to get fields.
// This is going to translate into:
// fooString="";
// barInt=0;
#include "foo.h"
#undef STRING
#undef int
}
#endif // defined( DEFINE_ZERO )
// etc...
#endif // end else clause for defined( FOO_H )
#endif // end else clause for defined( FIELD_LIST )
I've used the preprocesser to calculate fixed-point numbers from floating point values used in embedded systems that cannot use floating point in the compiled code. It's handy to have all of your math in Real World Units and not have to think about them in fixed-point.
Example:
// TICKS_PER_UNIT is defined in floating point to allow the conversions to compute during compile-time.
#define TICKS_PER_UNIT 1024.0
// NOTE: The TICKS_PER_x_MS will produce constants in the preprocessor. The (long) cast will
// guarantee there are no floating point values in the embedded code and will produce a warning
// if the constant is larger than the data type being stored to.
// Adding 0.5 sec to the calculation forces rounding instead of truncation.
#define TICKS_PER_1_MS( ms ) (long)( ( ( ms * TICKS_PER_UNIT ) / 1000 ) + 0.5 )
Yet another foreach macros. T: type, c: container, i: iterator
#define foreach(T, c, i) for(T::iterator i=(c).begin(); i!=(c).end(); ++i)
#define foreach_const(T, c, i) for(T::const_iterator i=(c).begin(); i!=(c).end(); ++i)
Usage (concept showing, not real):
void MultiplyEveryElementInList(std::list<int>& ints, int mul)
{
foreach(std::list<int>, ints, i)
(*i) *= mul;
}
int GetSumOfList(const std::list<int>& ints)
{
int ret = 0;
foreach_const(std::list<int>, ints, i)
ret += *i;
return ret;
}
Better implementations available: Google "BOOST_FOREACH"
Good articles available: Conditional Love: FOREACH Redux (Eric Niebler) http://www.artima.com/cppsource/foreach.html
Maybe the greates usage of macros is in platform-independent development.
Think about cases of type inconsistency - with macros, you can simply use different header files -- like:
--WIN_TYPES.H
typedef ...some struct
--POSIX_TYPES.h
typedef ...some another struct
--program.h
#ifdef WIN32
#define TYPES_H "WINTYPES.H"
#else
#define TYPES_H "POSIX_TYPES.H"
#endif
#include TYPES_H
Much readable than implementing it in other ways, to my opinion.