问题标签 [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++ - 严格的指针别名:针对特定问题的任何解决方案?
我有一个由违反严格的指针别名规则引起的问题。我有一个T
来自模板的类型和一些Int
相同大小的整数类型(如sizeof
)。我的代码基本上执行以下操作:
因为T
是一些可以具有构造函数的任意(除了大小限制)类型,所以我不能将T
and合并Int
。(这仅在 C++0x 中允许,甚至 GCC 还不支持)。
有什么办法可以重写上述伪代码以保留功能并避免破坏严格的别名规则?请注意,这是一个模板,我无法控制T
; some_other_t
赋值和随后的比较确实发生在模板代码中。
T
(作为记录,如果包含任何位字段,上述代码在 GCC 4.5 上开始中断。)
c++ - 严格的指针别名:通过“易失性”指针/引用访问是一种解决方案吗?
在特定问题、自我回答和评论之后,我想了解它是否是正确的解决方案、解决方法/黑客或完全错误。
具体来说,我重写了代码:
作为:
带有volatile
指针的限定符。
让我们假设在我的情况下对待T
是int
有道理的。这种通过volatile
引用访问是否解决了指针别名问题?
作为参考,来自规范:
[注意: volatile 是对实现的提示,以避免涉及对象的激进优化,因为对象的值可能会通过实现无法检测到的方式进行更改。详细语义见 1.9。一般来说,volatile 的语义在 C++ 中与在 C 中的语义相同。 — 尾注]
编辑:
上面的代码至少在 GCC 4.5 上确实解决了我的问题。
c++ - boost::bind 打破了严格的别名规则?
使用 Boost 1.43 和 GCC 4.4.3,以下代码
生成以下警告
boost/function/function_base.hpp:321:警告:取消引用类型双关指针将破坏严格别名规则
在不设置 -fno-strict-aliasing 的情况下消除这些警告的正确方法是什么?
c - 取消引用类型双关指针将破坏严格的别名规则
作为更大程序的一部分,我使用以下代码从文件中读取数据。
现在我被告知使用-O2
,我收到以下 gcc 警告:
warning: dereferencing type-punned pointer will break strict-aliasing rules
谷歌我发现了两个正交的答案:
对比
最后,我不想忽略警告。你会推荐什么?
[更新]我用实际功能替换了玩具示例。
c++ - C 别名规则和 memcpy
在回答另一个问题时,我想到了以下示例:
第 1 行打破了别名规则。但是,第 2 行是可以的。别名规则。问题是:为什么?编译器是否有关于 memcpy 等函数的特殊内置知识,或者是否有其他一些规则可以使 memcpy 正常?有没有办法在标准 C 中实现类似 memcpy 的函数而不破坏别名规则?
c++ - 违反严格混叠规则的演员表
我有一个函数需要一个 unsigned long* 并且需要将它传递给一个采用 unsigned int* 的外部库,并且在这个平台上 unsigned int/long 的大小相同。
这会产生一个警告,说它违反了严格的别名规则。有解决办法吗?
谢谢
编辑:我很抱歉不清楚。该代码是一个原子更新,所以绕过库来存储它不是一种选择。我可以下到汇编,但我想在 C++ 中执行此操作。
c - 是无符号字符 a[4][5]; 一个[1][7];未定义的行为?
C 标准中未定义行为的示例之一是 (J.2):
— 数组下标超出范围,即使对象显然可以使用给定的下标访问(如在给定声明 int a[4][5] 的左值表达式 a[1][7] 中)(6.5.6)
如果声明从int a[4][5]
to更改unsigned char a[4][5]
,访问是否a[1][7]
仍会导致未定义的行为?我的观点是它没有,但我从其他人那里听到了不同意的意见,我想看看其他一些可能成为 SO 专家的想法。
我的推理:
按照对 6.2.6.1 第 4 段和 6.5 第 7 段的通常解释,对象的表示
a
是sizeof (unsigned char [4][5])*CHAR_BIT
位,并且可以作为unsigned char [20]
与对象重叠的类型数组来访问。a[1]
具有unsigned char [5]
作为左值的类型,但在表达式中使用(作为运算符的操作数[]
,或等效地作为运算+
符 in的操作数*(a[1]+7)
),它衰减为类型的指针unsigned char *
。的值
a[1]
也是一个指向“表示”a
形式的字节的指针unsigned char [20]
。这样解释,加7a[1]
有效。
c - 为什么没有为此代码生成严格别名警告?
我有以下代码:
我正在使用以下命令行编译代码:
我正在使用 GCC 4.5.0。我希望编译器打印出警告:
但它从来都不是。对于其他情况,我可以打印出警告,但我想知道为什么在这种情况下不是这样。这不是打破严格别名规则的明显例子吗?
c++ - “取消引用类型双关指针将破坏严格的别名规则”警告
我使用了一个代码,将 enum* 转换为 int*。像这样的东西:
编译代码(g++ 4.1.2)时,我收到以下警告消息:
我用谷歌搜索了这条消息,发现只有在启用严格别名优化时才会发生这种情况。我有以下问题:
- 如果我留下这个警告的代码,它会产生潜在的错误代码吗?
- 有没有办法解决这个问题?
- 如果没有,是否可以从源文件内部关闭严格别名(因为我不想为所有源文件关闭它,也不想为此源文件制定单独的 Makefile 规则)?
是的,我实际上需要这种别名。
c++ - C++ 中的简单存储类和严格的别名
我有以下代码用于存储一个小类。
gcc 4.4 警告我在storage::get()
返回时违反了严格的别名规则。
AFAIK,我没有违反任何规则。我实际上违反了严格的别名还是 gcc 在这里变得很挑剔?
有没有办法在不禁用严格别名的情况下让它免费警告?
谢谢
编辑:
另一方面,以下实现没有给出任何警告:
编辑:
gcc 4.5 及更高版本不会发出警告 - 所以显然这只是对严格别名规则的误解或 gcc 4.4.x 中的错误