Cornstalks
Cornstalks

Reputation: 38228

Why does this static_assert only fail with clang on OS X and nowhere else?

The following code:

#include <cstdint>
#include <type_traits>

enum class Enum : std::uint64_t {
    zero,
};

static_assert(std::is_same<std::make_unsigned<Enum>::type, std::uint64_t>::value, "");

fails to compile on OS X with clang:

$ clang++ -std=c++11 -c t.cpp
t.cpp:8:1: error: static_assert failed ""
static_assert(std::is_same<std::make_unsigned<Enum>::type, std::uint64_t>::value, "");
^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated

However, this same file works okay with clang 3.8/3.7.1/3.7/3.6/3.5.1/3.5/3.4.1/3.3 on gcc.godbolt.org.

On my system, clang is just the normal version from Xcode 7.3.1:

$ clang++ --version
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

What gives? This clearly seems to be a bug in clang on my system, but it's not clear to me why this would fail with clang from Xcode but not any of the other versions of clang. Is Xcode's clang distribution significantly different?

Upvotes: 3

Views: 1048

Answers (1)

T.C.
T.C.

Reputation: 137425

This is not a bug; the behavior is mandated by the standard. [meta.trans.sign] says for the enumeration case

type shall name the unsigned integer type with smallest rank ([conv.rank]) for which sizeof(T) == sizeof(type), with the same cv-qualifiers as T.

In platforms where sizeof(unsigned long long) == sizeof (unsigned long), std::uint64_t may be defined as either, but std::make_unsigned<Enum>::type must name unsigned long.

Upvotes: 5

Related Questions