Reputation: 70556
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++?
Upvotes: 5
Views: 5566
Reputation:
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.
Upvotes: 7