1

I know the words "portable" and "macro" don't often go together, but my code is generally riddled with #ifdef _DEBUG tags (I use VS2012) that confirm desired outcomes. I want to make my code portable to Unix systems.

My understanding, based on this post, is that Visual Studio uses _DEBUG and the C-standard uses NDEBUG, but that their functions are different (_DEBUG flags debug mode, NDEBUG flags assertions).

If I want my code to be as portable as possible, should I use #ifndef NDEBUG if I only ever want those lines of code to run when asserts are active? What are the consequences of this within Visual Studio? It seems to work but I want to make sure there's nothing I'm missing; ie. why would microsoft use _DEBUG when there's a perfectly good C-standard alternative? Historic reasons?

Community
  • 1
  • 1
quant
  • 21,507
  • 32
  • 115
  • 211
  • "as portable as possible" - does that mean across all architectures (16 bit, 32 bit, 64 bit), all operating systems, all processor, all endian-ness??? I would restate what level of portability you are looking for. I also would not recommend using Microsoft as the basis for doing anything "portable" (their header files are filled with "WIntel" implementations). – franji1 Sep 15 '13 at 22:47
  • 1
    @franji1 I don't think endianness and architecture is relevant in this instance. As I am asking about macros I would consider the solution to be portable if it works on any standard c++ compiler under windows and linux. Let's assume the rest of my code is completely portable. Everywhere. – quant Sep 15 '13 at 22:51
  • Just making sure you looked at the primary portation issues. MSVS based projects are typically NOT very portable. – franji1 Sep 15 '13 at 23:29

4 Answers4

3

That ship sailed a long time ago, MSVC complied because resistance was futile. This works as you'd expect:

#ifdef NDEBUG
#pragma message("Release build selected")
#endif

That macro doesn't completely fall from the sky, like some do. Project + Properties, C/C++, Preprocessor, Preprocessor definitions setting. It works not because the compiler joined the Borg, the IDE did. Or to be a bit more specific, the project template did. A very good excuse :)

So no, making macros portable is completely not a problem. It only takes getting your makefile correct.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
2

I don't know the real reason for MS not using the NDEBUG macro, and defining the _DEBUG instead. My my guess is that it is related to the definition of _ASSERT instead of assert.

The problem with assert() is that the C standard defines requires it to print a line to the console and abort the program. But Windows programs don't usually have a console, so MS thought that it would be nice to pop up a window instead. But that assert() pops up a window would not be standard compliant, so the developed a similar but different macro:_ASSERT, and a different macro to control its behavior: _DEBUG.

A similar mess exists with the _UNICODE and UNICODE macros, but that's another story...

Note that in the default configuration of a Visual C++ project, in debug mode _DEBUG is defined, but NDEBUG is not. While in release mode _DEBUG is not defined, but NDEBUG is. So for your own code, you can use any one of them. But naturally, if you want to be portable you should use NDEBUG, as the _DEBUG name is reserved to the compiler implementation.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Note: MS does use NDEBUG for asserts (as expected). But they also have other macros that are specifically theirs (just like any other compiler). – Martin York Sep 15 '13 at 23:03
1

Albeit a bit contrived, you can do this to make it somewhat portable-er

#if defined(__unix__) && defined(NDEBUG)
#define _DEBUG
#endif
Steven Huang
  • 490
  • 4
  • 16
1

As far as I know, the only thing (by standard), NDEBUG should affect is assert macro. Therefore, if one wants to add their debugging facilities, he adds his own macro definitions like _DEBUG (which do not affect or depend on NDEBUG).

To make your debugging code portable, you're likely better off defining your own macro for the same purpose.

Then as an option, you could turn it on and off, say, depending on NDEBUG presence.

Artem Tokmakov
  • 1,135
  • 10
  • 7
  • AFAIK, there is nothing in C that prevents you from using `NDEBUG` to conditionally compile your own code. – rodrigo Sep 15 '13 at 23:09
  • 2
    Well, yes, you sure can. It's just that your code will depend one something which is supposed to turn off and on assert macro. Which may not be a bad thing of course. – Artem Tokmakov Sep 16 '13 at 01:33