of -fno-exceptions, ObjC++, __EXCEPTIONS, Mac vs. Linux ... and Qt

Hello,

I have a bit of a debate going on with a Qt dev, about whether or not it is sufficient under all conditions to test __EXCEPTIONS to know whether C++ exceptions are enabled: https://bugreports.qt.io/browse/QTBUG-61034

I think the summary at http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro should be followed, but Thiago's opinion is that Apple introduced a bug in Xcode 8 (= way after clang 3.6).

His argument: clang on Linux does not define __EXCEPTIONS when -fno-exceptions is given (unless you target MachO).

I'm more inclined to consider that inconsistency a bug in clang.

Where is the truth in this matter?

Thanks,
René

It sounds like it’s an Apple bug: __EXCEPTIONS is enabled for all language dialects if -fexceptions is passed (and not defined if -fno-exceptions is passed), but it is not defined for Objective-C++ or C++ when exceptions are enabled by default. This bug is also present in clang 4.0, but only with a macos target (e.g. x86_64-apple-macos), but not with an ios target.

David

but it is not defined for Objective-C++ or C++ when exceptions are
enabled by default.

That seems like yet something else, but how can this be an Apple bug (it happens
with Ubuntu builds from llvm.org too when targetting Darwin)? What's more, how
can it be a bug if it's documented and explained?

I can imagine why __EXCEPTIONS would be set if any kind of exceptions are
enabled; it's only for history reasons one might expect that token to be C++-
specific (cf. the -fcxx-exceptions argument; I haven't yet checked if -
fexceptions actually controls both C++ and ObjC exceptions).

This bug is also present in clang 4.0, but only with a
macos target (e.g. x86_64-apple-macos), but not with an ios target.

The lack of consistency certainly seems to be a bug.

So far as I can tell, __EXCEPTIONS behaves as documented: it is defined if Clang will emit exceptional destructor cleanups. How it is defined on Darwin vs. Linux vs. Obj-C++ is all based on crazy different platform defaults that I can’t untangle. It sounds like Obj-C++ on Mac enables Obj-C exceptions by default, which means we keep around C++ destructor cleanups, so __EXCEPTIONS is defined.

In all cases, the __has_feature(cxx_exceptions) test will indicate if ‘try’ and ‘throw’ are available.

So far as I can tell, __EXCEPTIONS behaves as documented: it is defined if

Yes, but only on Mac, at least according to the documentation I linked to. But that's 4 versions old by now, things could have changed in the meantime.

Clang will emit exceptional destructor cleanups. How it is defined on
Darwin vs. Linux vs. Obj-C++ is all based on crazy different platform
defaults that I can't untangle.

That too should be documented...

It sounds like Obj-C++ on Mac enables Obj-C
exceptions by default, which means we keep around C++ destructor cleanups,
so __EXCEPTIONS is defined.

I'm pretty sure that when I tried on Linux (targetting Linux) I also saw -fobjc_exceptions in the commandline arguments.

R.