【问题标题】:Is this use of std::array undefined behavior? [duplicate]这是对 std::array 未定义行为的使用吗? [复制]
【发布时间】:2012-11-08 00:44:22
【问题描述】:

可能重复:
Aliasing `T*` with `char*` is allowed. Is it also allowed the other way around?

我使用chars 中的std::array 来保存未知原始类型的值,其长度不超过 10 个字节,如下所示:

std::array<char, 10> val;
*reinterpret_cast<double*>(val.data()) = 6.3;
//blah blah blah...
double stuff = *reinterpret_cast<double*>(val.data());

我已经读过通过char * 来回转换不是未定义的,因为编译器假定char * 可以为任何类型的值设置别名。当值被放置在(我假设是)对象内的chars 数组中时,这仍然有效吗?

注意:我知道我可以在这里使用联合,但这会导致我正在做的事情有大量的样板代码,如果有必要我想避免它,因此这个问题。

【问题讨论】:

  • 不同的问题,相同的答案。
  • 同一个问题,不同的词。 ;-]

标签: c++ c++11 undefined-behavior


【解决方案1】:

是的,std::array&lt; char, 10 &gt; 不满足double 的对齐要求,所以reinterpret_cast 会引发UB。

改用std::aligned_storage

【讨论】:

  • 对齐!当然,这是我什至没有想到的事情。感谢您提供该链接,这正是我所需要的。
【解决方案2】:

数组包含在什么中并不重要。

该标准甚至不考虑事物周围的内容(这是基本的),但确实支持与char 序列的转换。

要直接通过reinterpret_cast 和赋值执行此操作,您需要正确对齐缓冲区。

另一种方法是使用memcpy,它不关心对齐。

在一个相关问题上,降低到二进制级别通常不是一个好主意。例如,编译器的简单版本更改可能会使二进制序列化数据文件无法访问。无论如何,这样做的一个主要驱动因素是原始性能考虑。

【讨论】:

  • 是否支持任意char*double*?我认为指针转换可能是有损的。考虑一个具有不同大小指针的 ABI。
  • 什么样的编译器更改会导致这种情况发生?
  • char 指针具有与任何指针一样细粒度的寻址分辨率,与 void 相同。如果缓冲区未正确对齐,则指针转换可能是有损的。无论如何,数据复制可能会效率低下
猜你喜欢
  • 1970-01-01
  • 2021-11-15
  • 2018-05-03
  • 1970-01-01
  • 2021-03-15
  • 2020-06-15
  • 1970-01-01
相关资源
最近更新 更多