Is there a cross platform way to detect debug mode compilation? If not, then how to do it for the top compilers; MSVC, GNU & MINGW, mac, clang, intel.
For example MSVC you can detect debug mode like the following.
#if defined _DEBUG
// debug related stuff here
#else
// release related stuff here
#endif
For many or most compilers, "debug" mode is a multifaceted concept that includes several orthogonal settings. For example, with gcc, you can add debugging symbols to the output code using -g, enable optimizations using -O, or disable assert() macros using -DNDEBUG (to define the NDEBUG macro). In my work, we have deployed production code with many combinations of these enabled or disabled. We have left -g on in order to attach to running processes and troubleshoot them using gdb (in which case we usually have to fight with the spaghetti -O produced), left assertions on to get more information about persistent errors across releases, and disabled optimizations for legacy codebases written under a more permissive interpretation of "undefined behavior" (until we could fix/replace it).
Since the NDEBUG macro actually affects the semantics of the generated code (and some libraries change their ABIs when the macro is defined or not), that's probably the most portable answer to your question. However, if you're using that macro to detect optimized builds portably, you'll probably have mixed success.
Below code should be work:
#ifdef defined DEBUG || defined _DEBUG
#else
#endif
Related
Which preprocessor define should be used to specify debug sections of code?
Use #ifdef _DEBUG or #ifndef NDEBUG or is there a better way to do it, e.g. #define MY_DEBUG?
I think _DEBUG is Visual Studio specific, is NDEBUG standard?
Visual Studio defines _DEBUG when you specify the /MTd or /MDd option, NDEBUG disables standard-C assertions. Use them when appropriate, ie _DEBUG if you want your debugging code to be consistent with the MS CRT debugging techniques and NDEBUG if you want to be consistent with assert().
If you define your own debugging macros (and you don't hack the compiler or C runtime), avoid starting names with an underscore, as these are reserved.
Is NDEBUG standard?
Yes it is a standard macro with the semantic "Not Debug" for C89, C99, C++98, C++2003, C++2011, C++2014 standards. There are no _DEBUG macros in the standards.
C++2003 standard send the reader at "page 326" at "17.4.2.1 Headers"
to standard C.
That NDEBUG is similar as This is the same as the Standard C library.
In C89 (C programmers called this standard as standard C) in "4.2 DIAGNOSTICS" section it was said
https://port70.net/~nsz/c/c89/c89-draft.html
If NDEBUG is defined as a macro name at the point in the source file
where <assert.h> is included, the assert macro is defined simply as
#define assert(ignore) ((void)0)
If look at the meaning of _DEBUG macros in Visual Studio
https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros
then it will be seen, that this macro is automatically defined by your сhoice of language runtime library version.
I rely on NDEBUG, because it's the only one whose behavior is standardized across compilers and implementations (see documentation for the standard assert macro). The negative logic is a small readability speedbump, but it's a common idiom you can quickly adapt to.
To rely on something like _DEBUG would be to rely on an implementation detail of a particular compiler and library implementation. Other compilers may or may not choose the same convention.
The third option is to define your own macro for your project, which is quite reasonable. Having your own macro gives you portability across implementations and it allows you to enable or disable your debugging code independently of the assertions. Though, in general, I advise against having different classes of debugging information that are enabled at compile time, as it causes an increase in the number of configurations you have to build (and test) for arguably small benefit.
With any of these options, if you use third party code as part of your project, you'll have to be aware of which convention it uses.
The macro NDEBUG controls whether assert() statements are active or not.
In my view, that is separate from any other debugging - so I use something other than NDEBUG to control debugging information in the program. What I use varies, depending on the framework I'm working with; different systems have different enabling macros, and I use whatever is appropriate.
If there is no framework, I'd use a name without a leading underscore; those tend to be reserved to 'the implementation' and I try to avoid problems with name collisions - doubly so when the name is a macro.
Be consistent and it doesn't matter which one. Also if for some reason you must interop with another program or tool using a certain DEBUG identifier it's easy to do
#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa
Unfortunately DEBUG is overloaded heavily. For instance, it's recommended to always generate and save a pdb file for RELEASE builds. Which means one of the -Zx flags, and -DEBUG linker option. While _DEBUG relates to special debug versions of runtime library such as calls to malloc and free. Then NDEBUG will disable assertions.
Despite the name, NDEBUG has nothing to do if you are creating a debug build or not, it controls whether assertions (assert()) are active or not. I would not base anything else on it, as you may want to have debug builds without assertions or release builds with assertions from time to time and then you must set NDEBUG accordingly but that doesn't mean you also want all other code to be debug or release code.
From the perspective of compilers, there is not such thing as a debug build. You tell the compiler to build code with a specific set of settings and if you want to use different settings for different kinds of builds, then this is something you actually made up yourself and the compiler knows nothing about that. You may actually have 50 different build styles and not just release and debug (profile, test, deploy, etc.), so it's up to you how these styles are identified in your own code. If you need pre-processor tags for these, you define how those are named and the same name space rules applies as for everything else you'd define in your code.
MSVC defines _DEBUG in debug mode, gcc defines NDEBUG in release mode. What macro can I use in clang to detect whether the code is being compiled for release or debug?
If you look at the project settings of your IDE, you will see that those macros are actually manually defined there, they are not automatically defined by the compiler. In fact, there is no way for the compiler to actually know if it's building a "debug" or "release", it just builds depending on the flags provided to it by the user (or IDE).
You have to make your own macros and define them manually, just like the IDE does for you when creating the projects.
Compilers don't define those macros. Your IDE/Makefile/<insert build system here> does. This doesn't depend on the compiler, but on the environment/build helper program you use.
The convention is to define the DEBUG macro in debug mode and the NDEBUG macro in release mode.
You can use the __OPTIMIZE__ flag to determine if optimization is taking place. That generally means it is not a debug build since optimizations often rearrange the code sequence. Trying to step through optimized code can be confusing.
This probably is what those most interested in this question really are attempting to figure out.
There is no such thing as a debug mode in a command line compiler. That is a IDE thing: it just sets up some options to be sent to the compiler.
If you use clang from the command line, you can use whatever you want. The same is true for gcc, so if with gcc you use NDEBUG you can use just the same.
From here: http://google-glog.googlecode.com/svn/trunk/doc/glog.html
Debug Mode Support
Special "debug mode" logging macros only have an effect in debug mode and are compiled away to nothing for non-debug mode compiles.
What does "debug mode" mean w.r.t C++ program?
Can we say a program is in debug mode when we are using GDB on it?
There's three sides to "debug mode".
A lot of libraries (including standard libraries) will insert debug-helping code (array bounds checking, invariant assertions, that sort of thing) when they are compiled in debug mode. They remove these checks in production/non-debug mode to help performance.
Compilers have debug switches. The set debug macros that the libraries use to detect whether you are compiling for debug or not, and insert debug symbols in the produced binaries. This helps debuggers make the link between the binary code that is running and the source code that generated it.
Running an program in a debugger is a "runtime debug mode". You can run an executable in a debugger whether or not it was built for debugging. You'll get more information with a debug build.
All three of these "debug modes" are independent. You could (usually) compile library debug checks in a production build by setting the appropriate macros/defines manually without asking the compiler to output debug symbols.
None of this is specific to C++ (or C). A lot of other languages have these concepts.
"Debug mode" can refer to a lot of things, but in this case it refers to compiling without the NDEBUG macro defined. From the page that you linked to (emphasis mine):
The DFATAL severity logs a FATAL error in debug mode (i.e., there is no NDEBUG macro defined), but avoids halting the program in production by automatically reducing the severity to ERROR.
C++ programs (like C) usually have different build configurations based on preprocessor macros, which can be passed from the command line.
The canonical debug mode flag is the macro NDEBUG, which if defined means you are not in debug mode. (It could be more clearly named PRODUCTION, but sadly it's named in terms of what it's not.)
NDEBUG is standard, and ancient. It is used by the <cassert> header, which is known as <assert.h> in C. Its official function is to make the assert macro into a no-op, but it also usually affects the C++ standard library in terms of checking bounds and requirements.
For example, g++ -DNDEBUG myProg.cpp -o myProg should compile without runtime features related to debugging.
Note that this is different from producing symbolic support for the debugger, which is controlled with -g on GCC, or other flags for other platforms.
The game engine I am working with is too slow in the debug build and is impossible to debug the game. One of the things I would like is for the compiler to inline small functions (especially in Vector/Matrix and container classes). This may or may not speed up the game in debug build. Before profiling heavily and trying to figure out bottlenecks I thought I would try this first as I would have to do minimal work and the results may be promising.
So, is there a way to get the Visual C++ compiler to inline functions in debug builds?
Project options -> C/C++ -> Optimization -> Inline Function Expansion. Turn this to /Ob2. Do this in your Debug configuration.
In Release, inline function expansion is implied by other optimization settings, so even though by default all configurations say "Default" for the setting, the behavior is indeed different.
I believe Debug builds should have inline expansion behavior the same as release; there's really no reason not to.
http://msdn.microsoft.com/en-us/library/47238hez.aspx
You're confusing two compiler options. /O influences optimization, including inlining. /ZI creates the PDB file for debugging. They can be set independently.
It may be useful to clone the "Debug" configuration, though, and create a "Debug-optimized" configuration with both /O1 and /ZI.
You might try __forceinline. Be sure to read about debug builds on that page (turn off the /Ob0 option).
My suspicion is that this will not change the performance very much. Another thing to try if you haven't already is just to add symbols to a release build. It works fairly well for debugging a lot of issues.
DEBUG is defined by Visual Studio when a project is compiled in Debug mode so:
#ifdef DEBUG
inline void fn() {
#else
void fn() {
#endif
I generally program & compile under Linux with gcc and -ansi flag; but I've been forced with doing a job in Visual C++ and whenever I compile my C code I get all the Microsoft warnings like
'fscanf': This function or variable
may be unsafe. Consider using fscanf_s
instead.
I get these despite following some steps on MSDN Developer's site for setting up an ANSI C project, but all the _s ("secure") calls are not ANSI C!
Any suggestions on putting Visual C++ Studio in a strict ANSI-only mode?
Thanks.
As mentioned in another answer, #define'ing _CRT_SECURE_NO_WARNING will address the specific warnings you mentioned in your question.
If you're really looking for an ANSI-only mode, the closest thing is the /Za compiler switch. Inside the Visual Studio IDE, you can find it in the project's Properties dialog (under Configuration Properties | C/C++ | Language | Disable Language Extensions).
Note that virtually all Windows apps build with Microsoft's compiler extensions enabled; e.g., I don't think you'd even be able to consume Windows SDK headers with /Za set. If your code truly is strict ANSI, you should be OK. If you have a few Windows-specific pieces in a project that is mostly strict ANSI, you could probably isolate those sources and only build those indivudal source files with /Za unset.
These warnings can be suppressed by defining _CRT_SECURE_NO_WARNING
Go to Procect Settings -> Preprocessor and add _CRT_SECURE_NO_WARNING
This isn't forcing compiler to comply with ANSI. Just suppresses use ..._s warnings
One way to suppress specific warnings is to add something like the following to the source.
#if defined( _WIN32 )
#pragma warning(disable:4996)
#endif