4

Consider the following small test program for type traits of the GNU-extensions for __uint128_t

#include <limits>
#include <type_traits>

using uint128_t = __uint128_t;

int main()
{
    static_assert(std::is_unsigned<uint128_t>{}, ""); 
    static_assert(std::is_integral<uint128_t>{}, "");
    static_assert(std::numeric_limits<uint128_t>::digits == 128, "");
}

This works for g++ and libstdc++ (working example) and for clang++ and libc++ (working example), but not for the combination clang++ and libstdc++ (failing example).

Note that in all 3 cases I use the -std=gnu++1z flag.

Question: which combination of command-line parameters can successfully compile my test program for clang++ with libstdc++?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • This isn't about standard C++, this is about GNUC++. GCC fails the static asserts in `-std=c++1z` mode as well. From the standard's perspective, the way GCC has defined this type means it's not an integer type, just a custom type that happens to work pretty much like an integer type, and in standard-conforming mode the type traits reflect that. (I'm not sure how clang/libc++ have defined it. It's possible that it qualifies as an integer type in their implementation.) –  Dec 17 '16 at 12:49
  • @hvd note that in all 3 examples, I use `-std=gnu++1z`, and only in the case clang + libstdc++ did it fail – TemplateRex Dec 17 '16 at 13:03
  • I know, I commented in an attempt to clarify, not to dismiss your question. :) –  Dec 17 '16 at 13:09
  • For the `std::numeric_limits` on Apple platforms, see [Apple Clang and numeric_limits::max() is 0?](https://stackoverflow.com/q/41666815/608639) – jww Jul 20 '17 at 23:00

1 Answers1

6

In the non-standard -std=gnu++* modes, GCC predefines two macros that libstdc++ picks up to provide additional type traits:

$ g++ -std=gnu++1z -c -E -dM -xc++ /dev/null | grep INT_N
#define __GLIBCXX_BITSIZE_INT_N_0 128
#define __GLIBCXX_TYPE_INT_N_0 __int128

clang doesn't define these. Manually defining them, by passing -D__GLIBCXX_TYPE_INT_N_0=__int128 and -D__GLIBCXX_BITSIZE_INT_N_0=128 on the command line, makes your test case work with clang.

Adding these in clang itself is https://llvm.org/bugs/show_bug.cgi?id=23156, which is marked as fixed, but I'm not sure in which version. I have 3.8.1 installed locally, where it does not work, but I haven't checked 3.9.0.