C / C++ : Portable way to detect debug / release? - c++

Is there a standardized (e.g. implemented by all major compilers) #define that will allow me to distinguish between debug and release builds?

if believe
#ifdef NDEBUG
// nondebug
#else
// debug code
#endif
is the most portable.
But no compiler knows whether you are compiling debug or release, so this isn't automatic. But this one is used by assert.h in the c-runtime, so it's quite common. Visual Studio will set it, and I'm sure most other IDE's will as well.

Since there is no standard definition of debug or release, there isn't a way to do this. I can think of at least four different things that could be meant, and they can all be changed independently. Only two can be tested from within the code.
Compiler optimization level
Debugging symbols included in binary (these can even be removed at a later date)
assert() enabled (NDEBUG not defined)
logging turned off

Edit: I misread the question and waffled off on a different tangent!!! Apologies...
The macro _NDEBUG is used on Linux as well as on Windows...
If the binary is built and you need to determine if the build was release/debug, you can get a hexadecimal dump, if you see loads of symbols in it that would be debugging information...for example, under Linux, using the strings utility. There is a version available for Windows by SysInternals, available here on technet. Release versions of binary executables would not have the strings representing different symbols...
strings some_binary
Hope this helps,
Best regards,
Tom.

Best I could come with is
#ifndef NDEBUG
// Production builds should set NDEBUG=1
#define NDEBUG false
#else
#define NDEBUG true
#endif
#ifndef DEBUG
#define DEBUG !NDEBUG
#endif
Then you can wrap your debug code in if(DEBUG) { ... }.

Related

Using #define with build mode

Is it possible to define something when building in debug mode?
For example:
...
#ifdef ENABLE_DEBUG
/* This line will be executed if the program is built in debug mode */
#endif
...
This is indeed possible, because it's you who defines what "debug mode" means. There is no "standard" way to do this, because there is no such thing as "standard" debug mode. You, as the author of the buildsystem, are in control of all build settings. If you decide that you will define the macro DEBUG if and only if building in debug mode, you can of course use #ifdef DEBUG in your code to distinguish between debug and non-debug builds.
The closest "standard" thing you can get is that the macro assert is specified to do its check when macro NDEBUG is not defined, and do nothing when NDEBUG is defined. For this reason, IDEs normally set up build configurations so that debug builds do not define NDEBUG and optimised builds do.

How to obtain debug/release conditional compiling in C++ program

In a large C++/Qt/QMake/qtcreator project I would like to perform some tests, but only when I am compiling with the debug flag.
Is there a way to tell g++ that some small parts of the code have to be compiled only in debug mode ?
The standard way to do this is to depend on the macro NDEBUG, which is used by the macro assert() defined in <cassert>:
#ifdef NDEBUG
// release mode code
#else
// debug mode code
#endif
The opposite of #ifdef is #ifndef, and of course #else branches are optional.
If this macro doesn't work (for whatever reason), you
can try the macro QT_NO_DEBUG, which Qt uses for a similar purpose with Q_ASSERT(); and
should fix it so that NDEBUG is (un)defined correctly; it's required for <cassert> to work properly, and code you use may depend on it.

How can I know what OS I'm working in?

I need a function that can clear the screen in both Linux and Windows. To do this, I want to know if there are some instructions that can tell me what operating system I'm working with.
I have searched for solution and I found the following code:
void clear_screen()
{
#ifdef WINDOWS
std::system ( "CLS" );
#else
// Assume POSIX
std::system("clear");
#endif
}
There are two problems with this function:
I don't understand it.
-> for #ifdef WINDOWS, where is WINDOWS defined?
This code works in Linux but it doesn't work in Windows.
Note :
I'm using Windows XP.
I don't want any non-standard functionality ... such "curses"
Macros such as _WIN32, __gnu_linux__, __linux__ are defined by the compiler in question. You can find a comprehensive list of pre-defined compiler macros here.
_WIN32 is defined for both 32-bit and 64-bit environments of Windows.
You're looking for
// Windows, all variants (including 64-bit and ARM)
#ifdef _WIN32
or
#ifdef __unix__
These are defined by your compiler, and are not stored in a header file. Because of that, you don't need to #include a file first, and these #ifdefs will always give the correct result (unless you mess with the compiler)
WINDOWS is defined by your compiler, so this defines can be compiler-dependant. It's usefull in order to compile specific code depending on your OS.
There are various compiler-dependant macros. Unfortunately, they are not particularly useful, because they are not standardized and a C compiler for a particular OS does not necessarily #define them. I also suspect that they actually violate the C standard C11 7.1.3.
The 100% portable solution, which will compile on all C compilers, is to create such a constant yourself. Since C is a compiled language, you will have to compile your code differently for each OS anyhow. Simply add a file called os.c where you put a relevant #define or constant, then link this to your program. The only thing you need to change when compiling for a different OS is the make file path to your OS-specific os.c.

Executing only part of the code in Release mode

I have some C++ code that I'd like to debug. As it's often the case, my bug appears only in certain conditions that cannot be reproduced with tiny datasets, and it appears after going through multiple functions that I am sure work.
In particular, I first need to put all my data in an std::set which is very slow in debug mode (and reasonable in release), even when using an _ITERATOR_DEBUG_LEVEL 0 preprocessor directive. As such, I was thinking that there might have been a way to execute part of the code in release while only executing the relevant buggy part of the code in debug mode.
I tried doing something like :
#ifdef _DEBUG
#undef _DEBUG
#define MODIFIED_DEBUG
#define NDEBUG
#endif
// build my expensive datastructure etc. etc.
#ifdef MODIFIED_DEBUG
#undef MODIFIED_DEBUG
#undef NDEBUG
#define _DEBUG
#endif
// execute my buggy code
However, this is still as slow as in debug mode. I there any (easy) way to get the speed of the release mode only for part of my code ? Especially, since the slowness is mostly due to the STL.
(I guess I could compile a .lib that builds the data structure in release and use the library in my code in debug mode, but that's quite a pain just to debug a program!).
Alternatively, is there any trick like the _ITERATOR_DEBUG_LEVEL 0 definition to speed up the STL in debug mode ? I am using Visual Studio 2010.
You can build in release mode and surround the suspect code with
#pragma optimize("",off)
//...
#pragma optimize("",on)
or do it old-school - debug statements.

C++ determine if compiling with debug symbols without defining a preprocessor symbol

I have been using something like this:
int main(int argc, char *argv[])
{
#ifdef DEBUG
printf("RUNNING DEBUG BUILD");
#else
printf("Running... this is a release build.");
#endif
...
However this requires me to compile with -DDEBUG for the debug build. Does GCC give me some way for me to determine when I am compiling with debug symbols (-g flag) such as defining its own preprocessor macro that I can check for?
Answer is no. Usually these macros (DEBUG, NDEBUG, _DEBUG) are set by the IDE/make system depending on which configuration (debug/release) you have active. I think these answers can be of help:
C #define macro for debug printing
Where does the -DNDEBUG normally come from?
_DEBUG vs NDEBUG
I think the answer that I was looking for was essentially what Adam posted as a comment, which is:
The compiler's job does not include preprocessing, and in fact the compiler will choke on any preprocessor switches not handled by the preprocessor that make their way into code.
So, because the way to branch code has to leverage the preprocessor, it means by the time the compiler gets any code it's already one or the other (debug code or release code), so it's impossible for me to do what my question asks at this stage (after preprocessor).
So it is a direct consequence of the preprocessor being designed as a separate process for feeding the code through.