Artifact ID: 9711899e2fb6c4df269031eb0237e0b3622f8f7c20f478912acb8cf597bb40ac
Ticket: f245681931009283f80ed29241d0e31313f97115
clang: Feature detection via has_feature vs has_extension
User & Date: luismachuca 2019-08-16 18:19:16

  1. Change foundin to "all"
  2. Change icomment to:

    At present, supported features in Clang are detected via __has_extension in config/clang.hpp , unlike in other compilers such as GCC where they are detected via parsing of the reported values of __cplusplus and the compiler's version number.

    This is one of two ways of detecting features in Clang:

    __has_feature and __has_extension

    These function-like macros take a single identifier argument that is the name of a feature. __has_feature evaluates to 1 if the feature is both supported by Clang and standardized in the current language standard or 0 if not (but see below), while __has_extension evaluates to 1 if the feature is supported by Clang in the current language (either as a language extension or a standard language feature) or 0 if not.

    (Source: https://releases.llvm.org/4.0.0/tools/clang/docs/LanguageExtensions.html#feature-checking-macros )

    This difference in implementation has maybe unintended effects when compiling code using cxxomfort in Clang: code (and the library itself) will detect a certain feature is available despite the Standard not supporting or Emulating it and thus code relying on the implementation of the backport can fail silently or generate undue warnings. One such example is explicit_cast, which with all versions up to CXXOMFORT_DATE == 20190215 will generate the following warnings in Clang++ 3.x and 4.x:

    /usr/local/include/cxxomfort/impl/17-byte.hpp:156:2: warning: explicit conversion functions are a C++11 extension [-Wc++11-extensions]

    And the explicit_cast example in cxxomfort-examples errors out with messages such as the following, apparently due to setting up "explicit_cast" to be "static_cast", which doesn't have the same semantics in C++03:

    explicit_cast.cpp:70:12: error: no matching conversion for static_cast from 'myfoo' to 'mybar'
        dobar( explicit_cast<mybar>(foo2)); // <-- should work

    Other cxxomfort features might be also affected. Most likely: enum class emulation, local function emulation and stuff in <functional>.

    Proposed solutions:

    • Detection should take place using __has_feature for all Standard features, and library code should opt-in accordingly.
    • Detection should take place using __has_extension for all Standard extensions, and library code should opt-out accordingly.
    • Detection should take place either of the two on a per-feature basis, left to the user with a sensible default of __has_feature.
  3. Change login to "luismachuca"
  4. Change mimetype to "text/x-fossil-wiki"
  5. Change severity to "Important"
  6. Change status to "Open"
  7. Change title to:

    clang: Feature detection via has_feature vs has_extension

  8. Change type to "Code_Defect"