This doesn't seem quite right, but it's the best I could do. Is there a way to do this better? My goal is to use DEBUG when I'm developing by doing a 'cc -DDEBUG' at the prompt.

#ifndef DEBUG
#define ptrValues ptrvaluesRemote
#define ptrValues ptrValuesLocal

ptrLinks = (struct sLinkDescriptionLayout*) ptrValues();

Perhaps use NDEBUG (as used in assert.h) instead of making up your own. Also note that unless you put an ifdef around the two functions you might get a linkage warning (as one of the functions might be unused). A warning is undesirable, but so is putting the ifdef around the functions, which will result in one of the functions not being compiled and in time the function may rot.

Note that you might achieve the same end using the tool-chain to modify the symbol table.

Another alternative would be to name the two functions the same in two separate files and link one or the other as required - that would be a cleaner solution, but would need documenting.


Perhaps make ptrLinks and ptrValuesEtc the same type so that a cast is unnecessary.

Consider whether ptrLinks and ptrValuesEtc are correctly named:

  • they appear to the uninitiated (me) to mean different things;
  • also, one is a function and the other a pointer but their form is the same.
  • \$\begingroup\$ I like this answer. Do you see any problems with using NDEBUG on Windows? \$\endgroup\$ – EhevuTov Aug 3 '12 at 4:23
  • \$\begingroup\$ There is no problems with using NDEBUG on windows. It is used in DevStudio and is defined for release builds. \$\endgroup\$ – Martin York Aug 3 '12 at 4:33
  • 3
    \$\begingroup\$ I disagree with the idea of using NDEBUG. As there is a difference between Debug/Release and NDEBUG/ ! NDEBUG. The NDBUG flag basically turns assert on/off. I can see a situation where you want to turn asserts on in release mode to help diagnose a problem that only happens in release build. \$\endgroup\$ – Martin York Aug 3 '12 at 4:36
  • \$\begingroup\$ Great input. Thank you both. I have thought about wrapping the two functions in #ifdef but I am concerned about having the function code branch, one for production and one for debug. It's a tangential topic, but a good one. \$\endgroup\$ – EhevuTov Aug 3 '12 at 20:01
  • \$\begingroup\$ Keep assertion control (-DNDEBUG) separate from the rest of your debugging (so I agree 100% with @LokiAstari — and upvoted his comment too). \$\endgroup\$ – Jonathan Leffler Aug 18 '12 at 5:30

Not much prettier, but maybe preferable depending on how you need to use it later:

#ifdef DEBUG
#define DEBUG_FLAG 1
#define DEBUG_FLAG 0

ptrLinks = (struct sLinkDescriptionLayout*) DEBUG_FLAG?ptrValuesLocal():ptrValuesRemote();

The C preprocessor is simultaneously fantastic and terrible.

  • \$\begingroup\$ It would be nice if there was a ternary operator in the preprocessor \$\endgroup\$ – EhevuTov Aug 2 '12 at 20:32

I recommend making the function name macro into a function-like macro instead of an object-like macro — give it an empty argument list. Also, it is usually best to keep the logic positive, so use #ifdef rather than #ifndef. This is hardly critical here, but in more complex situations, it is a good guideline to follow.

These observations lead to:

#if defined(DEBUG)
#define ptrValues() ptrValuesLocal()
#define ptrValues() ptrvaluesRemote()

ptrLinks = (struct sLinkDescriptionLayout*) ptrValues();

Personally, I would also have:

 typedef struct sLinkDescriptionLayout sLinkDescriptionLayout;

Then I wouldn't need the struct in the cast:

ptrLinks = (sLinkDescriptionLayout *)ptrValues();

I'd probably go for a shorter name, too, (perhaps LinkDesc, but it depends on what the other names in the code are) but that's very much less critical.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.