根据 MSVC,具有易失性成员的结构不再是 POD
Struct with a volatile member no longer a POD according to MSVC
#include <cstdint>
#include <type_traits>
extern "C"
{
struct thread_shared_struct
{
volatile uint32_t ccr;
};
struct thread_shared_struct getStuff();
}
static_assert(std::is_pod<thread_shared_struct>::value, "thread_shared_struct isn't a POD");
int main(int argc, char** argv)
{
thread_shared_struct m = getStuff();
return 0;
}
当然,这个例子没有多大意义,但它是从更大的代码库中对我的问题的最小复制。
对于 GCC(主干)和 Clang(主干),这工作正常。
对于 MSVC (x64, 19.22),static_assert 失败并且 getStuff() 生成错误,因为它试图 return 一个与 C 调用约定不兼容的类型。
如果删除 "volatile",一切正常。
MSVC 认为 thread_shared_struct 不是 POD 类型是不是错了?
extern "C" 部分在 C 头文件中,需要保持原样。我如何从 C++ 中使用它?
来自the Microsoft documentation:
When a class or struct is both trivial and standard-layout, it is a POD (Plain Old Data) type.
后面描述文字类型,包括以下条件:
Additionally, all its non-static data members and base classes must be literal types and not volatile.
页面上其他任何地方都没有提及 "volatile"。
这一切都符合我们找到的 in the standard。
因此,我断定这是一个编译器错误。
getStuff() generates an error because it attempts to return a type that is not compatible with the C calling convention.
实际上,这只是一个警告 (C4190),您可以根据需要将其禁用。 Visual Studio on x86_64 只有一个调用约定(描述为 here)。您的代码仍然可以正常工作。 VS 只是警告你,如果你真的尝试在 C 中使用它,该类型将不起作用。extern "C"
并不意味着编译为 C。
但是,收到此警告确实表明该错误确实存在于编译器中,而不是简单地存在于 std::is_pod
的实现中。
此外,我建议在新代码中避免使用 POD 术语和 std::is_pod
特征,因为它们是 deprecated from C++20.
The extern "C" part is in a C header that needs to stay as is. How could I use it from C++?
任何 实际上 不需要类型来满足 VS 对 "POD" 的定义,尽管有类型特征,应该没问题。
#include <cstdint>
#include <type_traits>
extern "C"
{
struct thread_shared_struct
{
volatile uint32_t ccr;
};
struct thread_shared_struct getStuff();
}
static_assert(std::is_pod<thread_shared_struct>::value, "thread_shared_struct isn't a POD");
int main(int argc, char** argv)
{
thread_shared_struct m = getStuff();
return 0;
}
当然,这个例子没有多大意义,但它是从更大的代码库中对我的问题的最小复制。
对于 GCC(主干)和 Clang(主干),这工作正常。
对于 MSVC (x64, 19.22),static_assert 失败并且 getStuff() 生成错误,因为它试图 return 一个与 C 调用约定不兼容的类型。
如果删除 "volatile",一切正常。
MSVC 认为 thread_shared_struct 不是 POD 类型是不是错了?
extern "C" 部分在 C 头文件中,需要保持原样。我如何从 C++ 中使用它?
来自the Microsoft documentation:
When a class or struct is both trivial and standard-layout, it is a POD (Plain Old Data) type.
后面描述文字类型,包括以下条件:
Additionally, all its non-static data members and base classes must be literal types and not volatile.
页面上其他任何地方都没有提及 "volatile"。
这一切都符合我们找到的 in the standard。
因此,我断定这是一个编译器错误。
getStuff() generates an error because it attempts to return a type that is not compatible with the C calling convention.
实际上,这只是一个警告 (C4190),您可以根据需要将其禁用。 Visual Studio on x86_64 只有一个调用约定(描述为 here)。您的代码仍然可以正常工作。 VS 只是警告你,如果你真的尝试在 C 中使用它,该类型将不起作用。extern "C"
并不意味着编译为 C。
但是,收到此警告确实表明该错误确实存在于编译器中,而不是简单地存在于 std::is_pod
的实现中。
此外,我建议在新代码中避免使用 POD 术语和 std::is_pod
特征,因为它们是 deprecated from C++20.
The extern "C" part is in a C header that needs to stay as is. How could I use it from C++?
任何 实际上 不需要类型来满足 VS 对 "POD" 的定义,尽管有类型特征,应该没问题。