assert handling standard/platfform dependence - c++

I am using asserts in my program, and reaching production phase.
According to
http://www.cplusplus.com/reference/cassert/assert/
disable all of them for the production version by simply including a
line like:
#define NDEBUG
However, my Ubuntu C++ compiler said:
NDEBUG redefined [enabled by default]
And really,
#undef NDEBUG
does what I want. How much can I rely on this behavor to switch asserts on/off in config file, in case of a multi-platform config file?

Related

How can I make compiler version specific ifdef?

I've got the problem that my program will compile with g++10.2 and c++11 activated through cmake. but it will not compile with arduino dues arm-none-eabi-g++.exe compiler which also has c++11. The failure occurs because of one line that needs to be added for the arm compiler, but when I add that line to g++10.2 it won't compile.
So I need an #ifdef or some alternative to activate and deactivate the line specific for the compiler.
Like Deumaudit said in the comments:
Try to use __arm__, __aarch64__ or __ARM_ARCH macro
You'll probably be ok if you use #ifdef __arm__ or even #if defined(__arm__) || defined(__aarch64__)
If you're planning to add more supported platforms to your program, it might be a good idea to define some macros when building for a specific platform. I have my own _MY_APP_ARM macro defined in my CMakeLists.txt:
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
add_definitions(-D_MY_APP_ARM)
endif()
Which I can then use as #ifdef _MY_APP_ARM

warning: disabled expansion of recursive macro

I am currently building the GDCM project using MacOSX default compiler: clang. This compiler trigger a warning in its own header (see ref):
In file included from /Users/builder/external/GDCM/Source/MediaStorageAndFileFormat/gdcmJPEG12Codec.cxx:21:
/Users/builder/external/GDCM/Source/MediaStorageAndFileFormat/gdcmJPEGBITSCodec.cxx:336:9: warning: disabled expansion of recursive macro [-Wdisabled-macro-expansion]
if (setjmp(jerr.setjmp_buffer))
^
/Users/builder/llvm/llvm-rel-install/bin/../include/c++/v1/setjmp.h:40:21: note: expanded from macro 'setjmp'
#define setjmp(env) setjmp(env)
^
In file included from /Users/builder/external/GDCM/Source/MediaStorageAndFileFormat/gdcmJPEG12Codec.cxx:21:
/Users/builder/external/GDCM/Source/MediaStorageAndFileFormat/gdcmJPEGBITSCodec.cxx:724:9: warning: disabled expansion of recursive macro [-Wdisabled-macro-expansion]
if (setjmp(jerr.setjmp_buffer))
^
/Users/builder/llvm/llvm-rel-install/bin/../include/c++/v1/setjmp.h:40:21: note: expanded from macro 'setjmp'
#define setjmp(env) setjmp(env)
^
2 warnings generated.
This is either a clear bug in llvm header (which I find hard to believe), or I am missing something about the use of setjmp in C++98.
It's neither. It's not a bug in an LLVM header, it's not that you're missing something about the use of setjmp, it's that you've enabled a warning that happens to also trigger on perfectly valid code. Most warnings do. That's why they're warnings rather than errors. This particular warning happens to mostly trigger on valid code. That's why it's not enabled by default, not even included in -Wall, and not even included in -Wextra. Yet you enabled it anyway. That's fine, but then you should be prepared to deal with the results.

How do I detect if my code is being compiled with -fno-exceptions?

I'm writing a C++ library and I would like to make my API throw exceptions for invalid parameters, but rely on asserts instead when the code is compiled with -fno-exceptions.
Is there a way to detect at compile-time if I'm allowed to use exception handling?
Note that I'm writing a header-only library, so I don't have a configure phase and I don't have access to the build system to simply define a macro on the command line (and
I don't want to add burden to the user).
Since the Standard doesn't have any concept of "-fno-exceptions", of course the solution could be compiler-dependent. In this case I'm interested in solutions that work with both g++ and clang++, other compilers are not important for this project.
Thank you very much
GCC and Clang define the __EXCEPTIONS macro when exceptions are enabled, and do not define it when exceptions are disabled via -fno-exceptions.
Example:
#include <cstdio>
int main() {
#ifdef __EXCEPTIONS
puts("Exceptions are enabled");
#else
puts("Exceptions are disabled");
#endif
}

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.

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.