gpt4 book ai didi

c++ - 打包和指针别名,C 和 C++

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:23:05 24 4
gpt4 key购买 nike

union vec
{
#pragma pack(push,1)
struct
{
float x, y, z;
}
#pragma pack(pop)
float vals[3];
};

考虑上面的定义。 (除了 C99 中的匿名 union )

我想这个答案可能允许不同的答案,具体取决于编译器的选择、语言的选择和标准的选择。

  1. 我相信我可以保证(通过#pragma 编译器文档,而不是语言保证)sizeof(vec) == 3*sizeof(float)
  2. 因此,我相信我可以保证 &vec.x == &vec.vals[0] 等。
  3. 但是,我不确定从 v.x 写入然后从 v.vals[0] 读取是否合法(也就是说,不允许通过严格的别名) >

撇开包装不谈,我相信相关的措辞(至少来自 C99 标准)是:

  • a type compatible with the effective type of the object,

  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

最佳答案

  1. I believe I am guaranteed (via #pragma compiler documentation, not language guarantee) that sizeof(vec) == 3*sizeof(float)

是的,这是正确的,假设 #pragma 完全禁用了填充。


  1. As such, I believe I am guaranteed that &vec.x == &vec.vals[0], ect.

无论填充如何,都可以保证这一点,因为在结构/union 的开头永远不会有填充。参见示例 C11 6.7.2.1 §15:

There may be unnamed padding within a structure object, but not at its beginning.

这适用于所有版本的 C 标准,据我所知,也适用于所有版本的 C++ 标准。


  1. However, I am unsure if it is legal (that is, not allowed via strict aliasing), to write from v.x and then read from v.vals[0]

这在 C 中很好,但在 C++ 中是未定义的行为。

在 C 中,./-> 运算符保证这一点,C11 6.5.2.3:

A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member,95) and is an lvalue if the first expression is an lvalue.

脚注 95(信息性而非规范性)说:

95) If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.

C++ 没有这样的保证,因此通过 union 进行“类型双关”在 C++ 中是未定义的行为。这是两种语言之间的主要区别。

此外,C 有 union 的公共(public)初始序列 的概念,也在 C11 6.5.2.3 中指定:

One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.


您的示例中的数组和结构确实可能存在别名,因为您引用的部分是“在其成员中包含上述类型之一的聚合或 union 类型”。因此,写入结构然后通过数组读取该数据不会违反严格的别名,无论是在 C 还是 C++ 中。

但是,C++ 在处理 union 时有“事件成员”的概念,所以在 C++ 中,除了别名之外,这会由于其他原因给出不明确的行为 - 即 C++ 只保证最后一个 union 的书面成员可以安全地阅读。

关于c++ - 打包和指针别名,C 和 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46323266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com