问题标签 [strict-aliasing]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - char* 转换和别名规则
根据严格的别名规则:
Achar*
对任何不同类型的对象都是有效的。但现在的问题是,它会指向 &d 的同一个地址吗?C++ 标准对返回相同地址的保证是什么?
c - 修复取消引用类型双关指针将破坏严格混叠
在使用 GCC 编译特定程序时,我正在尝试修复两个警告。警告是:
警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]
两个罪魁祸首是:
和
传入_buf和传出_buf定义如下:
这似乎与我一直在研究的其他警告示例略有不同。我宁愿解决问题,也不愿禁用严格别名检查。
有很多使用联合的建议——对于这种情况,什么是合适的联合?
c - 如何在嵌入式系统中安全地执行类型双关
我们的团队目前正在将一些旧架构的代码移植到基于 ARM Cortex M3 平台的新产品中,该平台使用定制版本的 GCC 4.5.1。我们正在从通信链路读取数据,并尝试将原始字节数组转换为结构以干净地解析数据。在将指针转换为结构并取消引用后,我们收到警告:“取消引用类型双关指针将破坏严格别名规则”。
经过一番研究,我意识到由于 char 数组没有对齐规则并且结构必须是字对齐的,因此转换指针会导致未定义的行为(坏事)。我想知道是否有更好的方法来做我们正在尝试的事情。
我知道我们可以使用 GCC 的“属性((aligned (4)))”明确地对字符数组进行字对齐。我相信这将使我们的代码“更安全”,但警告仍然会使我们的构建变得混乱,并且我不想禁用警告以防这种情况再次出现。我们想要的是一种安全地做我们正在尝试的事情的方法,如果我们稍后在另一个地方尝试做一些不安全的事情,它仍然会通知我们。由于这是一个嵌入式系统,RAM 的使用和闪存的使用在某种程度上很重要。
可移植性(编译器和架构)不是一个大问题,这仅适用于一种产品。但是,如果存在便携式解决方案,那将是首选。
这是我们当前正在做的一个(非常简化的)示例:
c++ - 通过 C 强制转换访问结构的第一个字段是否违反了严格的别名?
这段代码是否违反了严格的别名?
更抽象地说,只要原始读/写操作类型正确,在不同类型之间进行强制转换是否合法?
c++ - 我什么时候可以打破别名规则?
我收到这个警告。我想要定义的行为,但我想保持此代码不变。我什么时候可以打破别名规则?
警告:取消引用类型双关指针将破坏严格别名规则 [-Wstrict-aliasing]
字符串是我自己的字符串,它是一个 POD。这段代码是从 C 调用的。S 可能是一个 int。字符串几乎是struct String { RealString*s; }
模板化和辅助函数。我做了一个静态断言来确保 String 是一个 pod,是 4bytes 并且 int 是 4bytes。我还写了一个断言来检查所有指针是否>= NotAPtr。它在我的 new/malloc 重载中。如果您建议,我也可以将该断言放入 String
考虑到我遵循的规则(主要是字符串是一个 pod 并且始终与 int 大小相同)如果我打破别名规则会很好吗?这是少数几次打破它的人之一吗?
linux - 类型双关警告
我想做这样的事情:
但 gcc 正在产生此警告:警告:取消引用类型双关指针将破坏严格别名规则。
出于严格别名的目的,我不认为我正在做的事情算作取消引用,因为我没有将取消引用的指针分配给指针变量。
我试过:
这没有任何区别。
redhat linux 版本 2.6.32-220,gcc 版本 = 4.4.6
有没有办法使用严格的别名警告,但仍然做这样的事情?
谢谢!
编辑
这些不起作用:
这有效:
大家对此怎么看?
c++ - 严格的混叠和对齐
我需要一种在任意 POD 类型之间进行别名的安全方法,明确考虑到 n3242 或更高版本的 3.10/10 和 3.11 符合 ISO-C++11。这里有很多关于严格别名的问题,其中大部分是关于 C 而不是 C++。我找到了一个使用联合的 C 的“解决方案”,可能使用本节
在其元素或非静态数据成员中包含上述类型之一的联合类型
从那我建立了这个。
我的问题是,可以肯定的是,这个程序按照标准是否合法?*
它不会给出任何警告,并且在使用 MinGW/GCC 4.6.2 编译时可以正常工作:
*编辑:如果不是,怎么能修改它是合法的?
c++ - uint32_t 和 uint8_t[4] 未定义行为的联合?
在这个答案的评论中,据说使用如下的联合将整数分成它们的字节是未定义的行为。在那个地方给出的代码与此相似但不完全相同,如果我更改了代码的未定义行为相关方面,请注明。
到目前为止,我认为这将是一种很好的方法来做类似的事情addr = {127, 0, 0, 1};
并获得相应 uint32_t
的回报。(我承认这可能会根据我的系统的字节顺序产生不同的结果。但是问题仍然存在。)
这是未定义的行为吗?如果是这样,为什么?(我不知道C++ 中的 UB 是什么意思是访问非活动的工会成员。)
C99
- 在这一点上,C99 显然非常接近 C++03。
C++03
- 在一个联合中,任何时候最多有一个数据成员处于活动状态,即任何时候最多可以有一个数据成员的值存储在一个联合中。C++03,第 9.5 节 (1),第 162 页
然而
- 如果一个 POD 联合包含多个共享一个公共初始序列的 POD 结构 [...],则允许检查任何 POD 结构成员的公共初始序列,同上。
- 如果两个 POD-struct [...] 类型具有相同数量的非静态数据成员,则它们是布局兼容的,并且相应的非静态数据成员(按顺序)具有布局兼容类型C++03,第 9.2 (14) 节,第 157 页
- 如果两个类型 T1 和 T2 是同一类型,则 T1 和 T2 是布局兼容类型。C++03,第 3.9 (11) 节,第 53 页
结论
- as
uint8_t[4]
和uint32_t
不是同一类型(我猜,一个严格的别名)(加上两者都不是 POD-structs/union)上面确实是 UB?
C++11
- 请注意,聚合类型不包括联合类型,因为具有联合类型的对象一次只能包含一个成员。C++11,脚注 46,第 42 页
c++ - 严格别名和 std::array 与 C 样式数组
当使用 gcc 4.7(在 OS X 上使用 MacPorts 构建的 g++-mp-4.7 (GCC) 4.7.0)编译以下代码时,我得到看似矛盾的结果。
当我尝试将 an 的一部分重新解释和取消引用std::array
为 an时,编译器不会抱怨,uint32_t
但在使用 C 样式数组时会抱怨。
示例代码:
编译命令是:
为什么他们会受到不同的对待?
c++ - 用作对象的封装字符数组是否违反了严格的别名规则
下面的类是否打破了严格的别名规则:
我对标准的解读是它是不正确的,但我不确定(我的用法是拥有一个对象数组T
+这些对象的一些元数据,但是可以在不手动分配内存的情况下控制对象构造/解构)作为分配的对象被用作new
标准中放置的示例。