rsjaffe
rsjaffe

Reputation: 5730

Is alignas legal when used for an inline static member?

MSVC throws an error when alignas is used with an inline static member variable while Clang does not. Which one is correct? Flags for clang: -O2 -std=c++2a. Flags for MSVC: /std:c++latest.

The error:

error C2024: 'alignas' attribute applies to variables, data members and tag types only

#include <iostream> //https://godbolt.org/z/q4ScM7
#include <atomic>
#include <random>
class PRNG {
public:
    alignas(128) inline static std::atomic<uint64_t> state{ [] {
        auto rd{ std::random_device{} };
        return static_cast<uint64_t>(rd()) << 32
            | static_cast<uint64_t>(rd());
    }() };
};

int main()
{
    std::cout << PRNG::state;
}

The following variation, where the initialization is separated from the definition and inline is not used, succeeds with both:

#include <iostream> //https://godbolt.org/z/rvq6AP
#include <atomic>
#include <random>
class PRNG {
public:
    alignas(128) static std::atomic<uint64_t> state;
};
alignas(128) std::atomic<uint64_t> PRNG::state{ [] {
    auto rd{ std::random_device{} };
    return static_cast<uint64_t>(rd()) << 32
        | static_cast<uint64_t>(rd());
}() };

int main()
{
    std::cout << PRNG::state;
}

And both accept alignas on an inline static when it is not a member variable:

#include <iostream> //https://godbolt.org/z/Kd9NEV
#include <atomic>
#include <random>

alignas(128) inline static std::atomic<uint64_t> state{ [] {
    auto rd{ std::random_device{} };
    return static_cast<uint64_t>(rd()) << 32
        | static_cast<uint64_t>(rd());
}() };

int main()
{
    std::cout << state;
}

Upvotes: 3

Views: 335

Answers (2)

Ahmed Anter
Ahmed Anter

Reputation: 650

In MSVC 2019 std:c++latest refers to Preview Features from the latest working draft and i think it is still buggy. so you should use std:c++17 and it will compile with no errors. /std

The /std:c++latest option enables the post-C++17 language and library features currently implemented in the compiler and libraries. These features may include changes from the C++20 Working Draft, defect updates that aren't included in C++17, and experimental proposals for the draft standard. For a list of supported language and library features, see What's New for Visual C++. The /std:c++latest option doesn't enable features guarded by the /experimental switch, but may be required to enable them.

Upvotes: 2

M.M
M.M

Reputation: 141628

In C++17 [dcl.align]/1 it says:

An alignment-specifier may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, or an exception-declaration.

In your code, state is a data member (static data members are data members), so the alignment-specifier is allowed.

So I would suggest reporting a compiler bug.

Upvotes: 2

Related Questions