[Development] clang and auto-setting of QT_NO_EXCEPTIONS

René J. V. Bertin rjvbertin at gmail.com
Thu May 25 23:51:05 CEST 2017


Thiago Macieira wrote:


>> It explains rather unambiguously that clang 3.6 and later set _EXCEPTIONS
>> `if C++ or ObjC exceptions are enabled` and that `To reliably test if C++
>> exceptions are enabled, use _EXCEPTIONS && __has_feature(cxx_exceptions),
>> else things won’t work in all versions of Clang in Objective-C++ files.`
> 
> We're testing __EXCEPTIONS, like we should.

I know English isn't my first native tongue, but I read the quote above as "if 
you want to be certain whether C++ exceptions are enabled, regardless of what 
clang version is being used and regardless of whether you're compiling C++ or 
ObjC++, then you should test __EXCEPTIONS in combination with 
__has_feature(cxx_exceptions)". 

> Please describe the environment in which:
>  a) -fno-exceptions is active
>  b) __EXCEPTIONS is defined
> 
> Provide the full command-line and the compiler version.

On OS X 10.9.5 with Qt 5.8.0 and *stock* clang 4.0 (clang version 4.0.0 
(tags/RELEASE_400/final)), building KF5 Kinit 5.32.0 with the following probe:
#ifdef __EXCEPTIONS
#if __EXCEPTIONS
#warning "__EXCEPTIONS is defined and true"
#else
#warning "__EXCEPTIONS is defined but false"
#endif
#else
#warning "__EXCEPTIONS is NOT defined"
#endif
#ifdef QT_NO_EXCEPTIONS
#warning "QT_NO_EXCEPTIONS is defined"
#else
#warning "QT_NO_EXCEPTIONS is NOT defined"
#endif


/opt/local/bin/clang++-mp-4.0  -DCMAKE_INSTALL_PREFIX=\"/opt/local\" -
DKF5_LIBEXEC_INSTALL_DIR=\"/opt/local/libexec/kde5/kf5\" -
DLIB_INSTALL_DIR=\"lib\" -DQT_CORE_LIB -DQT_DBUS_LIB -DQT_GUI_LIB -
DQT_MAC_USE_COCOA -DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_FROM_BYTEARRAY -
DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG -DQT_NO_SIGNALS_SLOTS_KEYWORDS -
DQT_NO_URL_CAST_FROM_STRING -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_QSTRINGBUILDER 
-DQT_WIDGETS_LIB -DTRANSLATION_DOMAIN=\"kinit5\" -D_DARWIN_C_SOURCE -
D_LARGEFILE64_SOURCE -I/path/towork/build/src/kdeinit -
I/path/to/work/kinit-5.32.0/src/kdeinit -
I/path/to/work/build/src/kdeinit/kdeinit5_autogen/include -
I/path/to/work/build/src -I/path/to/work/kinit-5.32.0/src -I/path/to/work/build 
-iframework /opt/local/libexec/qt5/Library/Frameworks -isystem 
/opt/local/libexec/qt5/Library/Frameworks/QtGui.framework/Headers -isystem 
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/OpenGL.framework/Headers 
-isystem /opt/local/libexec/qt5/Library/Frameworks/QtCore.framework/Headers -
isystem /opt/local/share/qt5/mkspecs/macx-clang -isystem 
/opt/local/include/KF5/KWindowSystem -isystem /opt/local/include/KF5 -isystem 
/opt/local/libexec/qt5/Library/Frameworks/QtWidgets.framework/Headers -isystem 
/opt/local/include/KF5/KCrash -isystem /opt/local/include/KF5/KI18n -isystem 
/opt/local/include/KF5/KConfigCore -isystem 
/opt/local/libexec/qt5/Library/Frameworks/QtDBus.framework/Headers  -O3 -
march=native -g -DNDEBUG -stdlib=libc++ -std=c++0x -fno-operator-names -fno-
exceptions -Wno-gnu-zero-variadic-macro-arguments -Wall -Wextra -Wcast-align -
Wchar-subscripts -Wformat-security -Wno-long-long -Wpointer-arith -Wundef -Wnon-
virtual-dtor -Woverloaded-virtual -Werror=return-type -Wvla -Wdate-time -
pedantic -arch x86_64 -mmacosx-version-min=10.9 -fvisibility=hidden -
fvisibility-inlines-hidden   -fPIC -std=gnu++11 -o 
CMakeFiles/kdeinit5.dir/kinit_mac.mm.o -c 
/path/to/work/kinit-5.32.0/src/kdeinit/kinit_mac.mm

kinit_mac.mm:81:2: warning: 
      #warning is a language extension [-Wpedantic]
#warning "__EXCEPTIONS is defined and true"
kinit_mac.mm:91:2: warning: 
      #warning is a language extension [-Wpedantic]
#warning "QT_NO_EXCEPTIONS is NOT defined"

When I add -fno-objc-exceptions __EXCEPTIONS is no longer defined and 
QT_NO_EXCEPTIONS is.

This is exactly as described in the linked document from llvm.org . Also exactly 
as described: when I use the exact same commandline with /usr/bin/clang++ (Apple 
LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)), the probe prints 

kinit_mac.mm:86:2: warning: 
      #warning is a language extension [-Wpedantic]
#warning "__EXCEPTIONS is NOT defined"
kinit_mac.mm:89:2: warning: 
      #warning is a language extension [-Wpedantic]
#warning "QT_NO_EXCEPTIONS is defined"


QT_NO_EXCEPTIONS is indeed defined with both compilers when compiling regular 
C++ files.

Did you do all your testing on Mac? 

> Ok, I could reproduce this. It's Apple's bug and regression.
> 
> $ /Applications/Xcode.app/Contents/Developer/Toolchains/
> XcodeDefault.xctoolchain/usr/bin/clang++ -fno-exceptions -std=c++11 -dM -E -
> xobjective-c++ /dev/null | grep __EXCEPTIONS
> #define __EXCEPTIONS 1

What Xcode version is this? Clang 3.6 was introduced with Xcode 6.3 . If your 
Xcode.app is older than that you're not seeing a regression introduced by Apple 
but a feature introduced upstream. (Admittedly it could be both, given Apple's 
role in LLVM & clang ^^)


> 
> $ /Applications/Xcode6.4.app/Contents/Developer/Toolchains/
> XcodeDefault.xctoolchain/usr/bin/clang++ -fno-exceptions -std=c++11 -dM -E -
> xobjective-c++ /dev/null | grep __EXCEPTIONS
> [nothing]





More information about the Development mailing list