Reputation: 5730
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
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
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