问题标签 [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.
wireshark - 如何使 tshark 可执行
下载并解压wireshark 1.7.1后,我做了一个禁用gtk的配置。但是,我无法做“make”它会引发以下错误。
cc1:警告被视为错误 packet-h248_annex_e.c:679:警告:取消引用类型双关指针将破坏严格的别名规则。
有人可以帮助构建和安装这个wireshark版本吗?
c++ - 对齐存储和严格别名
我目前正在使用aligned_storage 来实现类似于boost::optional 的“可选”类型。为了做到这一点,我有一个像这样的班级成员:
我使用placement new 来创建对象,但是我没有将返回的指针存储在任何地方。相反,我在我的所有成员函数中访问对象的底层类型(显然,通过也存储在我的 Optional 类型中的布尔标志进行检查以确保对象有效):
我的问题是这是否安全。我的理解是,我对放置 new 的使用改变了对象的“动态类型”,只要我继续使用该类型访问内存就可以了。但是,我不清楚是否必须保留从放置 new 返回的指针,或者是否允许我在需要访问它时只转换为基础类型。我已经阅读了 C++11 标准的第 3.10 节,但是我的标准语不够流利,无法确定。
如果可能的话,如果您能在回答中参考标准,我会感觉更好(它可以帮助我晚上睡觉:P)。
c - 严格的别名规则,误报还是误报?
我在 C 中遇到严格别名问题。我使用的是 GCC 4.7.1。
示例 1:
当使用 -fstrict-aliasing -Wstrict-aliasing=3 编译此代码时,我收到“警告:取消引用类型双关指针将破坏严格别名规则”
示例 2:
此代码在使用 -fstrict-aliasing 和 -Wstrict-aliasing=3 或 -Wstrict-aliasing=2 或 -Wstrict-aliasing=1 时不会发出警告
这两个示例都可以正常工作。
使用 union 也是未定义的行为,在我的情况下使用 memcpy() 太慢了。
那么,第一个示例是安全的(误报)还是第二个示例也是不安全的(误报)还是...?
谢谢。
c - 从指向 const 的指针中删除 const 是否遵守 C 中的严格别名,并引用同一个对象?
C 中的以下代码是否具有定义的行为?
我问是因为 6.5/7 将“与对象的有效类型兼容的类型的限定版本”列为有效别名。但是对象的有效类型是const int
,而且我不认为int
它是一个合格的版本const int
(尽管反过来也是如此)。int
两者都不const int
兼容(6.7.3/10)。
此外,6.3.2.3/2 表示您可以通过添加限定符来转换指针类型,并且生成的指针是相等的。6.3.2.3/7 说您可以转换任何两种指针类型(因此(int*)(&i)
允许转换本身)。但并不是说结果指针指向同一个对象,甚至是相等的。它所说的只是它可以转换回原始类型(在这种情况下const int*
)。也就是说,即使别名是合法的,我也不清楚标准是否保证我的指针转换确实会导致指向i
.
那么,标准是否真的定义了我的代码的行为,如果是的话,它在哪里定义?
我知道代码在实践中有效。我想到了一个假设的(和奇怪的)实现,它不起作用。我可以询问该实现是否符合标准(如果不符合,它违反了哪一部分),但如果我想象的实现在其他方面不符合,我不想混淆。如果有人认为它会帮助他们回答问题,我将描述实现。
c - 编写就地浮点类型提升循环的正确方法?
我有一个例程,它使用适当大小的数组来处理额外的字节,将单精度数据数组提升为双精度:
进入x
时应包含n
float
s,退出时应包含n
double
s:
我为什么要这样做?数字密集型代码中的混合精度迭代细化。出于这个问题的目的,您可以忽略原因,因为它确实无关紧要。
多个编译器可以dpromote
在启用严格别名的各种积极优化级别上处理逻辑。最近,一位编译器供应商(将保持匿名)决定重新索引我的循环,以便它是通过内存的前向遍历而不是向后遍历。如果你盯着代码半分钟,你会发现循环转换产生了完全的垃圾。
dpromote
启用所有 C99 严格混叠花哨的逻辑是否依赖于未定义的行为?我不明白为什么编译器会认为可以更改循环索引,除非代码正在做未定义的事情。
c++ - 原始类型指针之间的转换
以下是明确定义的:
未intPtr
正确对齐(至少在两种情况下的一种)。放在那里是违法的吗?UB 在任何阶段都在使用它吗?你怎么能用它,你怎么不能?
c++ - 绕过 C++ 严格别名规则
我想在容器中存储有限数量的项目。我不想使用数组,因为我想避免不必要的对象构造函数调用。std::vector
由于隐式调用,我不想使用malloc
(我想最小化对堆的访问以获得最大的缓存一致性)。
所以我开始定义自己的自定义容器,如下所示:
但是当我尝试实际使用这个容器时,我会收到关于违反严格别名规则的编译器警告。我已经阅读了严格别名,并且我理解为什么编译器优化会导致上述代码中断。
我该如何解决这个问题?
奇怪的是,我的编译器对我的自定义object_pool
类没有任何抱怨,除此之外,我将其用于关联 STL 数据结构的自定义分配器。该类看起来与上面的非常相似(使用 achar[]
并执行类似的转换)。我无法弄清楚两者之间的区别是什么。
c - GCC 别名检查 w/Restrict 指针
考虑以下两个片段:
当我编译该函数时,gcc-4.7.2 -Ofast -march=native -std=c99 -ftree-vectorizer-verbose=5 -S test.c -Wall
我发现 GCC 为第二个函数插入了别名检查。
我怎样才能防止这种情况,使得生成的程序集与 forfn1
的程序集相同fn0
?(当参数的数量从 3 个增加到 30 个时,参数传递方法 ( fn0
) 变得很麻烦,并且该fn1
方法中的别名检查数量变得荒谬。)
组装(x86-64,支持 AVX 的芯片);在 .LFB10 处混叠杂物
c - 在不违反 C99 中严格的别名规则的情况下使用 void * 键入双关语
我最近遇到了严格的别名规则,但我无法理解如何在void *
不违反规则的情况下执行类型双关语。
我知道这违反了规则:
而且我知道我可以安全地使用 C99 中的联合进行类型双关:
但是如何void *
在 C99 中安全地执行类型双关语?以下是否正确:
我怀疑代码仍然会破坏严格的别名规则,因为变量x
地址处的内存可以被修改x
和取消引用y
。
如果 type-punning 未定义 via ,那么C99void *
中的目的是什么?void *
c - 这个指针转换是否打破了严格的别名规则?
这是来自 Quake III Arena 的快速反平方根实现:
我注意到long int在 float的地址(转换为 a )i
处获取取消引用的值。然后,代码在将取消引用的值存储在into的地址(转换为 a )之前执行操作。long *
y
i
float *
i
y
这是否会破坏严格的别名规则,因为i
与 不是同一类型y
?
我认为也许它不会因为值被取消引用和复制;所以操作是在副本而不是原件上执行的。