For various reasons the code i'm working with is compiled using the -fno-exceptions option in MingW GCC 11.2. In certain places i'd like to make use of the parallel algorithms from C++17. However, when attempting to use those algorithms with policy set to std::execution::par, i get errors trying to compile: error: exception handling disabled, use '-fexceptions' to enable because of catch (const std::bad_alloc&) from utils.h.
Am i doomed to not being able to use those algorithms unless i enable exceptions?
Related
I have an RTOS project using C++ without exception support (-fno-exceptions). I'm trying to use -Og, but I find it gives me:
undefined reference to `std::terminate()'
This corresponds to exception handling.
The problem doesn't occur with the other -O options.
gcc is gcc-arm-none-eabi-7-2018-q2-update
Does -Og require exception handling for some reason?
Update
The trigger for this error can be the noexcept keyword.
It's an interesting conflict. Code is trying to say that it wants to use std::terminate() instead of try/except for its exceptions. Meanwhile, with -fno-exceptions, it isn't possible to throw an exception, because the throw will be a compile time error. So that might lead someone to think noexcept is ignored if -fno-exceptions is specified.
In my project which has no 'throw' statement at all, somehow there are particular points of seemingly innocent code that result in the compile error. Removing noexcept at the erroring locations causes the project to build and run properly.
If I make a small project I can't yet reproduce it.
I know C++ compiler allows to use -fexceptions and -fno-exceptions to enable and disable exception handling. Is there a way to disable or enable exception handling by just defining some preprocessor in the C++ source code file?
The same question was recently asked on a mailing list: http://comments.gmane.org/gmane.comp.gcc.help/48303
The answer is that you can do this:
#GCC pragma optimize "no-exceptions"
Now, whether you should do this is another matter, but suffice to say that you'd better know what you're doing if you go down this path.
This post relates a technical problem encountered in a recent software project, and allows the reader to benefit from the hard-earned solution to the problem.
Background
In my company, I'm the implementer and maintainer of an internal library that uses the Boost asio ("ASynchronous I/O") socket framework to achieve cross-platform data transfer over sockets. A colleague recently came to me with the following problem: her Blackberry 10 application, which linked and used my library, crashed within several seconds if the Wi-Fi router was unceremoniously turned off during a file transfer operation.
Enabling built-in tracing within the library showed us that the crash was occurring when the library called the boost::asio::write(boost::asio::ip::tcp::socket *, boost::asio::buffer) function with a socket that was not 'valid' (i.e., the socket may be unusable). Placing a try/catch(boost::system::system_error) block around the write() failed to catch anything -- the crash was obviously happening within Boost.
Because the crash occurred only in release builds, we could not use the debugger.
Technical Information
The QNX compiler, QCC, uses GNU 4.6.3
The version of Boost used is 1.48.0
Here is a typical command line invocation of the compiler:
/home/foobar/bbndk/host_10_1_0_238/linux/x86/usr/bin/QCC
-Vgcc_ntoarmv7le
-lang-c++
-x c++
-DLINUX -DQNX -DSUPPORT_LAN -DUSE_SQLITE_FOR_DATABASE
-Wno-psabi -Wno-write-strings
-O3
-DNDEBUG
-fno-strict-aliasing
-fPIC
-I/home/foobar/Libraries/BlackBerry_10/boost_1.48/include
...
-I/home/foobar/Libraries/BlackBerry_10/utfcpp_1.0/include
-o CMakeFiles/Internals.dir/ConfigFileSingleton.cpp.o
-c /home/foobar/myproject_dev/myproject/SDK/Internals/ConfigFileSingleton.cpp
Steps used to locate the problem source
We wrote a lightweight minimal app to try and reproduce the problem with far less code, first using raw sockets, then using Boost's ASIO. Had the crash occurred we could have assumed the problem was not caused by our proprietary library. Unfortunately, the crash was not reproducible, leading us to suspect our library was at fault.
We wrote a lightweight tracing framework for use within Boost's ASIO header files, instrumenting functions related to the problem. The framework outputted a string on entry and exit into/from these functions, enabling us to trace values of variables, too.
Using the tracing framework we were able to prove that the crash occurred in the boost::throw_exception() templated function (non-relevant #ifdef'd code removed). Boost calls this function when the system-level write operation fails on a "broken pipe":
template<class E> BOOST_ATTRIBUTE_NORETURN inline void throw_exception( E const & e )
{
//All boost exceptions are required to derive from std::exception,
//to ensure compatibility with BOOST_NO_EXCEPTIONS.
throw_exception_assert_compatibility(e);
throw enable_current_exception(enable_error_info(e));
}
Inserting traces and splitting the 'throw' statement into separate statements proved to us that the crash was occurring in the process of throwing the exception object. In all probability, something was going very wrong with the unwinding of the stack when the exception was being thrown.
The Solution
Once we realized it was most probably a compiler bug, rather than an application-level one, we examined the compiler options used to build the library. We ruled out a memory corruption because the Boost internal code is probably hardened and robust enough. Once we thought that release mode optimization may be the culprit, the distance was short to the solution: drop the optimization level from -O3 to -O2.
Once we did that the crash evaporated.
We have since modified the Blackberry.cmake file in the QNX toolchain to use "-O2" rather than the original "-O3":
SET(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
#SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")
. . .
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -fno-strict-aliasing -fPIC")
#SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -fno-strict-aliasing -fPIC")
In the light of this crash it might be advisable to use "-O3" with caution. The reason why our minimal app didn't reproduce the problem was because it was compiled with optimization level 2, not 3.
We're looking for an SSCCE for submitting to the QNX and/or GNU teams.
The complete solution description can be found above in the question. As per Dale's pointer, I provide a brief explanation of the solution here.
The crash was due to compiling Boost for Blackberry using the default optimization level 3. Once we dropped the optimzation level from -O3 to -O2 the crash evaporated.
We have since modified the Blackberry.cmake file in the QNX toolchain to use "-O2" rather than the original "-O3". In the light of this crash it might be advisable to use "-O3" with caution.
Is it possible to 'tell' compiler that if total number of warnings (while compiling a C++ program) are more than say 10 then stop compiling further, and emit an error?
Or is it possible to hack a compiler like clang to provide this functionality.
GCC has two options together would achieve this, from gnu online docs:
-Werror
Make all warnings into errors.
-fmax-errors=n
Limits the maximum number of error messages to n, at which point GCC bails out rather than attempting to continue processing the source
code.
This would make a build with any warnings fail though, the options just define when to stop parsing.
I haven't seen this kind of feature in gcc or clang. You can certainly try to patch it into either of them, both are open source. There is also -Werror (accepted by both compilers) which simply treats warnings as errors.
How about using -Werror to make warnings into errors and -fmax-errors=n to set the limit.
(Also, perhaps making your code completely warning free would be a good thing).
I wrote a program for an assignment in which I allocated memory in this way:
EdgeBucket* edgeTable[ n_scanlines ];. I understand that this is normally illegal in C, but I was not aware that it could also not be done in C++. However, when I compile it using g++, it gives no compile errors. But my grader is using a visual studio, and when he attempted to build my program, it gave errors stating that the length of the array must be constant. I normally compile my programs with the -ansi and -Wall options to ensure cross compiler integrity, but even that didn't detect this. I am concerned about my grades being compromised by this, so does anyone know why the -ansi compiler didn't catch this, and what can be done to prevent further cross compiler discrepancies?
Use -pedantic-errors flag. Example.
They are known as VLAs (Variable Length Arrays). The are legal in C from C99 and illegal in C++.