Over reliance on macros - c++

I feel, every time I read a C or C++ program, that half or more of it is just macros. I understand that macros can be cool but they are hard to track, debug, etc. Not to mention that most programming languages do not even define something like macros (although Perl6 will have something of the sort).
I personally always have found a way to write my code without using macros, whether it be with templates, multiple inheritance, etc. I have even felt I am not a good programmer because all the pros use macros and I try to avoid them as much as I can.
The question is, are there problems which cannot be solved without macros? Are macros ultimately a good/bad practice? When should I consider using a macro?

Yes, here's one. When you need to add tracing code to your program in such a way that one configuration contains it and the other completely omits you have to use macros.
Something like:
#ifdef WITH_LOGGING
#define LOG( x ) DoLog( x )
#else
#define LOG( x )
#endif
now you use it this way:
LOG( L"Calling blahblahblah with " + getSomeStringHardToCompute() );
and in the configuration with WITH_LOGGING you have that code and otherwise it is completely omitted - not even present in the binary, and therefore
it doesn't help others analyze your program
you get a smaller binary
the program doesn't waste time fo logging at all
the compiler can produce better optimized code.

You've been looking at some bad C++ code. The places I use macros are limited to:
header guards
very occasional conditional compilation
a general exception throwing macro
a general debugging/logging output macro
I don't think those four can be avoided.

Straight from Scott Myer's Effective C++ -> 1
Given the availability of consts and inlines, your need for the preprocessor is reduced, but it's not completely eliminated. The day is far from near when you can abandon #include, and #ifdef/#ifndef continue to play important roles in controlling compilation. It's not yet time to retire the preprocessor, but you should definitely plan to start giving it longer and more frequent vacations.

Debug behaviour may be controlled with constant flags or debug functions. So here is my list of unavoidables:
Multiple inclusion protection.
Macros are the only way of symbol stringification. assert macro, compact realization of const string & stringify(enum category value);
Example:
const char* stringify(enum category value)
{
#define c(x) case x: return #x;
switch(value) {
c(CIRCLE)
c(RECTANGLE)
c(TRIANGLE)
default: return "UNKNOWN";
}
#undef c // the most important part
}

Macros, of course, are also useful when you want to generate code during preprocessing. While this can be avoided using templates (see this SO question and discussion - Are C++ Templates just Macros in disguise?), you can use macros if it makes the life of your users easier - see how the 'googletest' project (https://github.com/google/googletest/) uses macros effectively. You obviously don't want to use macros to generate code that needs debugging, use templates instead.

I think that C++'s templates and inline functions make macros pretty much avoidable.
The ubiquitousness of macros is probably due to the fact that there are many C++ programmers that used to be C programmers. Such people will probably be proficient at using macros (because it sometimes really is the best or only solution in pure C) and might not see any point in learning the more complicated C++ features if they already know how to solve the problem. At least in the open source world, there are many C converts, so you naturally meet C paradigms. I don't think that you're a bad programmer if you avoid such a feature, many people do, just like GOTOs.
C (and therefore C++) is an extremely flexible programming language. This is great, because everyone can develop his own distinct style and solve most problems in several different ways. This, however, can also be considered a problem. In my opinion not a problem that should be solved by the language but by establishing conventions.
There are many features in C++ that can be safely ignored. Maybe there are weird special occasions where such a feature would really be the best approach, but in most cases, you can live without:
Friend classes
Macros
GOTOs
And more.
IMO, a senior C++ programmer should be able to at least read them all fluently - yet I expect a good programmer to consider carefully when and if to use an infamous feature.

There are many problems that I can't solve without macros.
For instance, serialization/deserialization of some structs
#define STRUCT_DESCRIPTION structname(MyStruct) member(int,a) member(double,b) member(long, c)
#include "declare_serializable_struct.h" // declares struct itself and generates serialization/deserializaton code
#undef STRUCT_DESCRIPTION
( BOOST_PP_SEQUENCE may also be used)
Another example - dispatching a messages using message map, i.e. generating switch like this:
switch(message_type)
{
case msg1: on_msg1(msg); break;
case msg2: on_msg2(msg); break;
...
}
and generate handler method declarations on_msgX(msg) in the same time using some message description table ("map")
Personally, I try to avoiod macros when possible, but I didn't succeed in this way.
However, lambdas in c++0x allows to inline arbitrary code into "user-or-library-defined languge statements" such a foreach loops, so macro realm lose a significant part :)

Macros are a solution for conditional compiling (by ifdef and ifndef). Here is the examples:
1)
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
//...
#endif
2)
#ifdef __cplusplus
#define BEGIN extern "C" {
#define END }
#define NULL (0);
#else
#define BEGIN
#define END
#define NULL ((void*)0);
#endif
//-------------------------
BEGIN
void my_function(char* str);
END
//-------------------------
void my_function(char* str)
{
if(str != NULL)
{
//...
}
}
But inline functions and templates replaces other usages of macros in C++.

I tend to avoid using macros as much as possible because of their obvious safety / debugging issues, however there are times when macros offer something that no other facility within the language does as elegantly, in which case I prefer to use a macro just because it makes my life (and those of my fellow developers) easier.
For example, I have created an Enum class, which wraps an enum in a struct (scope) and adds some functionality:
possibility of iteration (which implies an order of the values)
conversion to / from string (handy to read/write to a file, write to logs)
In order to create the enum, I use a macro which will automatically generate the converter (to and from) and the vector for iteration.
Of course I could do without one, after all the macro is only for code generation. But doing without one would mean violating DRY, and in my little own preferences "DRY" > "Don't use macros". Because once debugged the macro is safe, whereas a DRY violation is a nightmare for maintenance.
Now, I am all for ditching this macro as soon as I find how not to violate DRY. Ideas are obviously welcome... and an external script is NOT better ;)
My 2 cents.

I try to avoid macros too, but to expand on the debugging, I have not found a way to print file name, function name, and line number when debugging.
I typically have a header file called DebugLog.h with the following Macro
#define DEBUG(debugMessage) \
printf("%s | %s [%d] - %s\n", __FILE__, __PRETTY_FUNCTION___, debugMessage);
Using:
DEBUG("Test")
will output something like:
main.cpp | foo(void)[20] - Test
You can adjust the macro for C++, and other debugging statements. It's also possible to modify the macro to send the resulting string to a logger.

I've started working at a telecom company. The product code base is about 20 years old, and has to support many legacy products, while also trying to avoid duplicate code. the language used is C++03. I find lots of contstructs similar to the following
ClassA::methodA(...)
{
// Common code
...
#if defined(PRODUCT_A) || defined(PRODUCT_B)
// Code for Product A or Product B
...
#elif defined(PRODUCT_C)
// Code for product C
...
#endif
// Common code
...
}
Horrible stuff, I agree. So far, we haven't been able to find a better solution. At least with this approach, we can understand what the code is supposed to do by simple code-reading.

The question is, are there problems which cannot be solved without macros?
No.
are macros ultimately a good/back practice? When should I consider to use a macro?
In languages which don't support or honor the inline keyword, macros are a great way to re-use code, but at the same time avoid the overhead of a function call in any code that is tightly looped enough for that to make a huge difference.
Your rant about code being littered with macros is probably justified. There are indeed hard to debug and in some cases to read. But they do come in useful in the very small number of cases where optimisation like this is truly warranted.
Note that as of C99, C can now do explicit inline functions using the inline keyword, which reduces the need for macros and even has advantages over using macros.

Programming language macros are good for what all macros are good for: avoiding typing the same things over and over again. So if you find yourself writing same pieces of code in many places, why not make a macro out of it? Especially if you're writing a library, using macros can make life easier for someone trying to use that library. Take a look at almost any GUI toolkit (Qt being one example). They all make extensive use of macros.

Related

Preprocessor Macros for Constants - Bad Form?

Recently, I've been assigned to a project (C++) at work where there is a significant amount of string matching/parsing in an XML-ish document (similar to XML, but not quite; it's bizarre) As a result, in order to both increase readability and reduce copy/paste errors, I've placed several macros at the top of several of my source files. For reference, the macros are different in each file. For example:
#define CATAGEORY_PATH "properties/event/classifications/classification/#category"
#define CLASSIFICATION_PATH "properties/event/classifications/classification/#classification"
Is what I did considered bad form and/or is there a better way to do this? At the moment, I like this method as it is clear throughout the code what I have done, but something about #define for a string bothers me.
From the experienced coders in the crowd, what are your thoughts? Also, from the professional developers, what do you think? I apologize if the distinction offends anyone, but, in my experience, there can be a significant difference between both populations.
Thanks!
An alternative for constants is static const.
static const char category_path[] = "properties/event/classifications/classification/#category" ;
This way there is at least a little bit of type information decorated with it.

Are there any good uses of macros? [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 9 years ago.
Improve this question
As far as I know, macros rearrange the program text before the compiler even sees it properly, thus potentially causing problems. I hardly ever see them in C++ code, mostly in C.
The only good use I know of, is inclusion guards (#ifndef).
Is there anything else that needs to be done with macros and cannot be implemented in a cleaner way?
Logging and Exception.
A macro allows you to effortlessly capture __FILE__, __LINE__ and __func__. Oh sure you could write them manually each time, but frankly this is tedious and error prone (both __FILE__ and __func__ are C-string so you risk mixing them up).
Prior to C++11, you would usually define static_assert as a macro (a typedef that would be invalid if the condition is false), so it can be available from anywhere (namespace level, or function level) and still not be ambiguous (e.g. by using a line number).
The Boost.Preprocessor library is another good example of using macros to reduce the amount of highly redundant code, and another one that is less relevant with variadic templates.
Furthermore macros are widely used to "talk" to the compiler, e.g. checking what compiler you are running on, what version of the compiler, whether C++11 support is available, etc.
Yes, the X-macro trick will always be useful.
You put your data in one header (no #include guards!), then use a macro to conditionally expand it.
Example:
Data.h:
X(Option1, "Description of option 1", int, long)
X(Option2, "Description of option 2", double, short)
X(Option3, "Description of option 3", wchar_t*, char *)
MyProgram.cpp:
enum Options
{
#define X(Option, Description, Arg1, Arg2) Option,
# include "Data.h"
#undef X
};
char const *descriptions[] =
{
#define X(Option, Description, Arg1, Arg2) Description,
# include "Data.h"
#undef X
};
#define X(Option, Description, Arg1, Arg2) typedef void (*P##Option)(Arg1, Arg2);
# include "Data.h"
#undef X
It's not the prettiest sight, but it avoids code duplication and lets you keep everything in one place.
Macros can be defined from the compiler command line, with -DFOO, which would define the macro FOO. This is most often used for conditional compilation, e.g. a certain optimization that is known to work on some platforms but not on others. The build system can detect whether the optimization is viable an enable it using this kind of macro.
This is one of the few uses of macros that I believe can be used well. However, it's of course possible to abuse this feature as well.
The macros are considered error prone due to its characteristics, here we have some good examples of error prone macros:
Macros VS inline functions.
Macros containing if.
Multiple line macros.
Concatenation macros.
But they could be useful in some ways, for example, in order to make te code more readable when dealing with function pointers:
class Fred {
public:
int f(char x, float y);
int g(char x, float y);
int h(char x, float y);
int i(char x, float y);
// ...
};
// FredMemberFn points to a member of Fred that takes (char,float)
typedef int (Fred::*FredMemberFn)(char x, float y);
// Useful macro:
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
With the "Useful macro", you can call function pointers like this:
callMemberFunction(fred,memFn)('x', 3.14);
That is slightly more clear than:
(fred.*memFn)('x', 3.14);
Credits: C++ FAQ Lite.
Several uses (some may have been mentioned already..)
Logging: DEBUG(....), this is neat because the contents are only evaluated if the logging is active (so the macro could have a test for log level for example...) You cannot replace this with an inline function as the arguments will always be evaluated. However with c++11, there is a lambda trick which will avoid the evaluation, however the syntnax is cludgy so you'll end requiring a macro anyway to clean it up! :)
Code generation, I use lots of SFINAE tests, and it's easy to generate the test with a couple of macros rather than hand construct the test every time.
There are some code rewriting for optimization that seem not to be doable with template metaprogramming and need macros. Here is a probable example: C++ template for unrolling a loop using a switch?
Yes, they will still have uses such as for "message maps" in ATL, WTL, MFC.
For example, this is part of some personal code I have:
BEGIN_MSG_MAP(This)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
COMMAND_RANGE_HANDLER(IDOK, IDNO, OnButtonClick)
CHAIN_MSG_MAP(CDialogResize<This>)
END_MSG_MAP()
Or even specifying the layout of a window:
BEGIN_DLGRESIZE_MAP(This)
DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X)
DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X)
DLGRESIZE_CONTROL(IDC_EDITINPUT, DLSZ_SIZE_X)
END_DLGRESIZE_MAP()
Writing this without macros would involve a lot of unnecessary boilerplate code.
When you need to utilize platform, compiler, or implementation specific features. Typically, this is either to improve portability or to access features which are expressed differently in the systems you target (i.e. it may be written differently on the compilers you use).
And expanding on Matthieu's answer (+1): Assertions.
Writing exception-checking tests with macros is much easier than with functions.
#define TEST_THROWS(code) do { try { code; } catch (...) { pass(); } fail(); } while(0)
Note: example not tested
Extending on the answer from #Matthieu, I've used macros to add file and line logging to a legacy codebase. So this:
void MovePlayer(Vector3 position)
{
...
}
became something like:
#define MovePlayer(pos) MovePlayer_(pos, __FILE__, __LINE__)
void MovePlayer_(Vector3 position, const char* file, int line)
{
LogFunctionCall("MovePlayer", file, line);
...
}
By only changing one place in the codebase, I was able to log everywhere that the function got called during a complex test. If you do this to enough functions, it's very useful for tracing existing behaviour in old codebases.

Conversion of JSON logging macros to template functions... parameter names needed in code

I was assigned the task of updating a very old project a while back. The first thing I had to do was to expand the existing code to incorporate a new feature. As part of this I modified existing macros to print JSON representations of incoming messages (over CORBA, into C++ structs). I then incorporated boost program_options and a new logger and now I want to modernise the macros.
The problem is that I have no idea how to implement what I did with the macros with templates. The key problem is that I use the name of the parameters to the macros to access the fields of the struct:
//Defines the string that precedes the variable name in a JSON name-value pair (newline,indent,")
#define JSON_PRE_VNAME _T("%s,\n\t\t\t\t\"")
//Defines the string that follows the variable name in a JSON name-value pair (":) preceding the value
#define JSON_SEP _T("\":")
#define printHex(Y,X) _tprintf(_T("%02X"), (unsigned char)##Y->##X );
// ******** MACRO **********
// printParam (StructureFieldName=X, ParamType=Y)
// prints out a json key value pair.
// e.g. printParam(AgentId, %s) will print "AgentId":"3910"
// e.g. printParam(TempAgent, %d) will print "TempAgent":1
#define printParam(X,Y) if(strcmp(#Y,"%s")==0){\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T("\"%s\""),_logBuf,myEvent->##X);\
}else{\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T(#Y),_logBuf,myEvent->##X);\
}\
printBufToLog();
And it is used like this:
//CORBA EVENT AS STRUCT "event"
else if(event.type == NI_eventSendInformationToHost ){
evSendInformationToHost *myEvent;
event.data >>= myEvent; //demarshall
printParam(EventTime,%d);
printParam(Id,%d);
printParam(NodeId,%d);
}
and this results in JSON like this:
"EventTime":1299239194,
"Id":1234567,
"NodeId":3
etc...
Obviously I have commented these macros fairly well, but I am hoping that for the sake of anyone else looking at the code that there is a nice way to achieve the same result with templates. I have to say the macros do make it very easy to add new events to the message logger.
Basically how do I do "#X" and ##X with templates?
Any pointers would be appreciated.
Thanks!
There are some things that you cannot really do without macros, and for some specific contexts macros are the solution. I would just leave the macros as they are and move on to the next task.
Well, I would actually try to improve a bit the macros. It is usually recommended not to use ; inside macros, and with macros that contain more than a single statement wrap them in do {} while(0) loops:
#define printHex(Y,X) _tprintf(_T("%02X"), (unsigned char)##Y->##X )
// remove ; ^
// add do while here:
#define printParam(X,Y) do { if(strcmp(#Y,"%s")==0){\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T("\"%s\""),_logBuf,myEvent->##X);\
}else{\
_byteCount += _stprintf(_logBuf,JSON_PRE_VNAME _T(#X) JSON_SEP _T(#Y),_logBuf,myEvent->##X);\
}\
printBufToLog();\
} while (false)
This might help avoid small mistakes that would otherwise be hard to fix, as, for example uses of the macros with if:
if (condition) printHex(a,b);
else printHex(c,d);
// looks good, but would originally expand to a syntax error:
if (condition) _tprintf(_T("%02X"), (unsigned char)##Y->##X );;
else ...
Similarly
if (condition) printParam(a,b);
else ...
would expand to a whole lot of non-sense for the compiler even if it looks correct enough to the casual eye.
I think that in many cases it's better to use an external code generator... starting from a nice neutral definition it's easy to generate C++, Javascript and whatnot to handle your data.
C++ templates are quite primitive and structure/class introspection is just absent. By playing some tricks you can be able to do ifs and loops (wow! what an accomplishment) but a lot of useful techniques are just out of reach. Also once you get your hard to debug template trickery working, at the first error the programmer makes you get screens and screens of babbling nonsense instead of a clear error message.
On the other side you have the C preprocessor, that is horribly weak at doing any real processing and is just a little more (and also less) than a regexp search/replace.
Why clinging to poor tools instead of just implementing a separate code generation phase (that can easily be integrated in the make process) where you can use a serious language of your choice able to do both processing and text manipulation easily?
How easy would be to write a neutral easy-to-parse file and then using for example a Python program to generate the C++ struct declarations, the serialization code and also the javascript counterpart for that?

How to separate logging logic from business logic in a C program? And in a C++ one?

I am currently coding in C and I have lots of printfs so that I can track, at some times, the flow of my application. The problem is that some times I want more detail than others, so I usually spend my time commenting/uncommenting my C code, so I can get the appropriate output.
When using Java or C#, I can generally separate both my implementation code from the logging logic by using Aspects.
Is there any similar technique you use in C to get around this problem?
I know I could put a flag called DEBUG that could be either on or off, so I wouldn't have to go all around and comment/uncomment my whole code every time I want to either show or hide the printfs. The question is I'd like to also get rid of the logging logic in my code.
If instead of C I was coding in C++, would it be any better?
Edit
It seems there is an AspectC++, so for C++ there seems to be a solution. What about C?
Thanks
IME you cannot really separate logging from the algorithms that you want to log about. Placing logging statements strategically takes time and experience. Usually, the code keeps assembling logging statements over its entire lifetime (though it's asymptotic). Usually, the logging evolves with the code. If the algorithm changes often, so will usually the logging code.
What you can do is make logging as unobtrusive as possible. That is, make sure logging statements always are one-liners that do not disrupt reading the algorithm, make it so others can insert additional logging statements into an existing algorithm without having to fully understand your logging lib, etc.
In short, treat logging like you treat string handling: Wrap it in a nice little lib that will be included and used just about everywhere, make that lib fast, and make it easy to use.
Not really.
If you have variadic macros available, you can easily play games like this:
#ifdef NDEBUG
#define log(...) (void)0
#else
#define log(...) do {printf("%s:%d: ", __FILE__, __LINE__); printf(__VA_ARGS__);} while(0)
#endif
You can also have logging that's turn-off-and-onable at a finer granularity:
#define LOG_FLAGS <something>;
#define maybe_log(FLAG, ...) do { if (FLAG&LOG_FLAGS) printf(__VA_ARGS__);} while(0)
int some_function(int x, int y) {
maybe_log(FUNCTION_ENTRY, "x=%d;y=%d\n", x, y);
... do something ...
maybe_log(FUNCTION_EXIT, "result=%d\n", result);
return result;
}
Obviously this can be a bit tedious with only allowing a single return from each function, since you can't directly get at the function return.
Any of those macros and calls to printf could be replaced with something (other macros, or variadic function calls) that allows the actual logging format and target to be separated from the business logic, but the fact of some kind of logging being done can't be, really.
aspectc.org does claim to offer a C and C++ compiler with language extensions supporting AOP. I have no idea what state it's in, and if you use it then of course you're not really writing C (or C++) any more.
Remember that C++ has multiple inheritance, which is sometimes helpful with cross-cutting concerns. With enough templates you can do remarkable things, perhaps even implementing your own method dispatch system that allows some sort of join points, but it's a big thing to take on.
On GCC you could use variadic macros: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html . It makes possible to define dprintf() with any number of parameters.
Using additional hidden verbose_level parameter you can filter the messages.
In this case the logging loggic will only contain
dprintf_cond(flags_or_verbose_level, msg, param1, param2);
and there will be no need in separating it from the rest of code.
A flag and proper logic is probably the safer way to do it, but you could do the same at compile type. Ie. Use #define and #ifdef to include/exclude the printfs.
Hmm, this sounds similar to a problem I encountered when working on a C++ project last summer. It was a distributed app which had to be absolutely bulletproof and this resulted in a load of annoying exception handling bloat. A 10 line function would double in size by the time you added an exception or two, because each one involved building a stringstream from a looong exception string plus any relevant parameters, and then actually throwing the exception maybe five lines later.
So I ended up building a mini exception handling framework which meant I could centralise all my exception messages inside one class. I would initialise that class with my (possibly parameterised) messages on startup, and this allowed me to write things like throw CommunicationException(28, param1, param2) (variadic arguments). I think I'll catch a bit of flak for that, but it made the code infinitely more readable. The only danger, for example, was that you could inadvertently throw that exception with message #27 rather than #28.
#ifndef DEBUG_OUT
# define DBG_MGS(level, format, ...)
# define DBG_SET_LEVEL(x) do{}while(0)
#else
extern int dbg_level;
# define DBG_MSG(level, format, ...) \
do { \
if ((level) >= dbg_level) { \
fprintf(stderr, (format), ## __VA_ARGS__); \
} \
} while (0)
# define DBG_SET_LEVEL(X) do { dbg_level = (X); } while (0)
#endif
The ## before __VA_ARGS__ is a GCC specific thing that makes , __VA_ARGS__ actually turn into the right code when there are no actual extra arguments.
The do { ... } while (0) stuff is just to make you put ; after the statements when you use them, like you do when you call regular functions.
If you don't want to get as fancy you can do away with the debug level part. That just makes it so that if you want you can alter the level of debugging/tracing date you want.
You could turn the entire print statement into a separate function (either inline or a regular one) that would be called regardless of the debug level, and would make the decision as to printing or not internally.
#include <stdarg.h>
#include <stdio.h>
int dbg_level = 0;
void DBG_MGS(int level, const char *format, ...) {
va_list ap;
va_start(ap, format);
if (level >= dbg_level) {
vfprintf(stderr, format, ap);
}
va_end(ap);
}
If you are using a *nix system then you should have a look at syslog.
You might also want to search for some tracing libraries. There are a few that do similar things to what I have outlined.

Eliminating inherited overlong MACRO

I have inherited a very long set of macros from some C algorithm code.They basically call free on a number of structures as the function exits either abnormally or normally. I would like to replace these with something more debuggable and readable. A snippet is shown below
#define FREE_ALL_VECS {FREE_VEC_COND(kernel);FREE_VEC_COND(cirradCS); FREE_VEC_COND(pixAccum).....
#define FREE_ALL_2D_MATS {FREE_2D_MAT_COND(circenCS); FREE_2D_MAT_COND(cirradCS_2); }
#define FREE_ALL_IMAGES {immFreeImg(&imgC); immFreeImg(&smal.....
#define COND_FREE_ALLOC_VARS {FREE_ALL_VECS FREE_ALL_2D_MATS FREE_ALL_IMAGES}
What approach would be best? Should I just leave well alone if it works? This macro set is called twelve times in one function. I'm on Linux with gcc.
Usually I refactor such macros to functions, using inline functions when the code is really performance critical. Also I try to move allocation, deallocation and clean up stuff into C++ objects, to get advantage of the automatic destruction.
If they are broken then fix them by converting to functions.
If they're aren't broken then leave them be.
If you are determined to change them, write unit-tests to check you don't inadvertently break something.
Ideally, I would use inline functions instead of using macros to eliminate function call overhead. However, basing from your snippet, the macros you have would call several nested functions. Inlining them may not have any effect, thus I would just suggest to refactor them into functions to make them more readable and maintainable. Inlining improves performance only if the function to be inlined is simple (e.g. accessors, mutators, no loops).
I believe this is your decision. If the macros are creating problems when debugging, I believe it is best to create some functions that do the same things as the macros. In general you should avoid complicated macros. By complicated I mean macros that do something more than a simple value definition.
Recommended:
// it is best to use only this type of macro
#define MAX_VALUE 200
The rest is not recommended (see example below):
// this is not recommended
#define min(x,y) ( (x)<(y) ? (x) : (y) )
// imagine using min with some function arguments like this:
//
// val = min(func1(), func2())
//
// this means that one of functions is called twice which is generally
// not very good for performance