c – “转换为标准布局的第一个成员”类型惩罚规则是否扩展到数组?

c – “转换为标准布局的第一个成员”类型惩罚规则是否扩展到数组?,第1张

概述具体来说,我在一个友好的C包装器中包装一个C API. C API具有相当标准的形状: struct foo {...};void get_foos(size_t* count, foo* dst); 我想做的是,通过将一个打字的包装器数组直接传递给C api,并通过一系列完整性检查static_assert()来节省自己的额外副本. class fooWrapper { foo raw_; 具体来说,我在一个友好的C包装器中包装一个C API. C API具有相当标准的形状:
struct foo {...};voID get_foos(size_t* count,foo* dst);

我想做的是,通过将一个打字的包装器数组直接传递给C API,并通过一系列完整性检查static_assert()来节省自己的额外副本.

class fooWrapper {  foo raw_;public:   [...]};std::vector<fooWrapper> get_foo_vector() {  size_t count = 0;  get_foos(&count,nullptr);  std::vector<fooWrapper> result(count);  // Is this OK?  static_assert(sizeof(foo) == sizeof(fooWrapper),"");  static_assert(std::is_standard_layout<fooWrapper>::value,"");  get_foos(&count,reinterpret_cast<foo*>(result.data()));  return result;}

我的理解是它是有效的代码,因为所有访问的内存位置都符合规则,但我想确认.

编辑:显然,只要reinterpret_cast< char *>(result.data()n)== reinterpret_cast< char *>(result.data())n * sizeof(foo)为true,它就可以在今天所有的主要编译器.但我想知道标准是否同意.

解决方法 首先,这不是打字.你正在做的reinterpret_cast只是一种覆盖的做法& result.data().foo_.类型punning通过指向另一种类型的指针/引用来访问一种类型的对象.您正在访问其他类型的子对象.

其次,这不起作用. Pointer arithmetic is based on having an array(为了指针算术的目的,单个对象充当1个元素的数组).并且矢量< T>由fiat定义以产生Ts的数组.但是T的数组不等于T的某个子对象的数组,即使该子对象的大小与T相同,T也是标准布局.

因此,如果get_foos在其给定的foos数组上执行指针运算,那就是UB.哦,当然,它几乎肯定会奏效.但语言的答案是UB.

总结

以上是内存溢出为你收集整理的c – “转换为标准布局的第一个成员”类型惩罚规则是否扩展到数组?全部内容,希望文章能够帮你解决c – “转换为标准布局的第一个成员”类型惩罚规则是否扩展到数组?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1238999.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存