alignas 用于内联静态成员时是否合法?
Is alignas legal when used for an inline static member?
当 alignas
与 inline static
成员变量一起使用时,MSVC 会抛出错误,而 Clang 不会。哪一个是正确的? clang 的标志:-O2 -std=c++2a
。 MSVC 的标志:/std:c++latest
.
错误:
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;
}
以下变体,其中初始化与定义分开并且 inline
未使用,两者都成功:
#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;
}
当 inline static
不是成员变量时,它们都接受 alignas
:
#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;
}
在 C++17 [dcl.align]/1 中它说:
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.
在您的代码中,state
是数据成员(静态数据成员是数据成员),因此允许使用对齐说明符。
所以我建议报告编译器错误。
在 MSVC 2019 std:c++latest 中指的是最新工作草案中的预览功能,我认为它仍然存在问题。
所以你应该使用 std:c++17 并且它会编译没有错误。
/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.
alignas
与 inline static
成员变量一起使用时,MSVC 会抛出错误,而 Clang 不会。哪一个是正确的? clang 的标志:-O2 -std=c++2a
。 MSVC 的标志:/std:c++latest
.
错误:
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;
}
以下变体,其中初始化与定义分开并且 inline
未使用,两者都成功:
#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;
}
当 inline static
不是成员变量时,它们都接受 alignas
:
#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;
}
在 C++17 [dcl.align]/1 中它说:
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.
在您的代码中,state
是数据成员(静态数据成员是数据成员),因此允许使用对齐说明符。
所以我建议报告编译器错误。
在 MSVC 2019 std:c++latest 中指的是最新工作草案中的预览功能,我认为它仍然存在问题。 所以你应该使用 std:c++17 并且它会编译没有错误。 /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.