Search code examples
c++visual-c++static-asserticc

static_assert and Intel C++ compiler


Reading cppreference.com:

A static assert declaration may appear at block scope (as a block declaration) and inside a class body (as a member declaration)

OK, now I have the following code:

struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        // This is just a sample; I removed real code from this method.
        return std::max(alignof(__m128), __alignof(__m256));
    }

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message");
};

Neither MSVC 2015 nor Intel C++ 16.0.2 compile this code (the former shows "error C2131: expression did not evaluate to constant" and the latter shows "function call must have a constant value in a constant expression" error and points to call of maxAlignment in static_assert).

But MSVC 2015 Update 1 does compile the following code, while Intel C++ 16.0.2 does not:

template <typename T, std::size_t Alignment>
struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        return std::max(std::alignment_of<T>::value, Alignment);
    }

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message");
};

foo_t<__m128, 16> foo {};
// foo_t<__m128, 33> boo {};  // here `static_assert` will stop compilation

(So, MSVC can handle static_assert when it's inside a template class body)

But the following code is compiled successfully by both of the compilers (static_assert is outside of a class body; it appears at a block scope):

struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        return std::max(alignof(__m128), __alignof(__m256));
    }
};

static_assert(0 == ((foo_t::maxAlignment() -1) & foo_t::maxAlignment()), "some message");

My question is: Did I miss something or is that Intel C++ compiler's error?


Solution

  • If I recall it right constexpr functions can't be used until they are fully defined and class-member constexpr functions are undefined until the class is defined and it means that you can't use constexpr member-function inside the class-scope static_assert which defines this very function.

    But you can make this function standalone(it is already static anyway) and it will do the job. It should compile everywhere.