当我可以打破混叠规则
When CAN i break aliasing rules?
我收到这个警告。我想要定义的行为,但我想保持代码的原样。我什么时候可以打破别名规则?
警告:取消引用类型punned指针将破坏严格的别名规则[-Wstrict aliasing]
字符串是我自己的字符串,它是POD。这段代码是从C调用的。S可能是一个int。字符串几乎是struct String { RealString*s; }
,但却是模板化的和辅助函数。我做了一个静态断言,以确保String是一个pod,是4字节,int是4字节。我还写了一个断言,它检查所有指针是否都是>=NotAPtr。它在我的新malloc过载中。如果你建议,我也可以把断言放在字符串中
考虑到我所遵循的规则(主要是字符串是一个pod,大小总是与int相同),如果我打破了别名规则,那会好吗?这是为数不多的一次打破它的权利吗?
void func(String s) {
auto v=*(unsigned int*)&s;
myassert(v);
if(v < NotAPtr) {
//v is an int
}
else{
//v is a ptr
}
}
memcpy
。对char*
的双关语也是如此(例如,您可以使用std::copy
)。
如果您不能按照建议将代码更改为2个函数,为什么不呢(需要C99编译器,因为它使用uintptr_t
-对于较旧的MSVC,您需要自己定义它,2008/2010应该可以):
void f(RealString *s) {
uintptr_t int = reinterpret_cast<uintptr_t>(s);
assert(int);
}
标准指定了一组最小的操作,所有符合要求的实现都必须以可预测的方式处理这些操作,除非它们遇到翻译限制(因此所有赌注都被取消)。它并不试图定义实现必须支持的所有操作,以适合任何特定目的。相反,对超出授权范围的行动的支持被视为执行质量问题。作者承认,一个实施可能是符合要求的,但质量太差,以至于毫无用处。
像您这样的代码应该可用于用于低级别编程的高质量实现,并且以预期的方式表示内存中的内容。它不应该被期望用于其他类型的实现,包括那些将"实现质量"问题解释为邀请人们尝试以低质量但符合要求的方式行事的实现。
struct String
{
union
{
RealString*s;
int i;
};
};
- 函数向量_指针有不同的原型,我可以构建一个吗
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 为什么我可以通过引用修改常量返回
- 我可以在 C++ 中的函数体之外进行操作吗?
- 我可以重新分配/覆盖std::字符串吗
- C++-我可以创建另一个类的成员并在构造函数中使用它吗
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么我可以使用比分配的内存更多的内存
- 在一个读写器队列中,我可以用volatile替换原子吗
- 我可以把基础班提升为儿童班吗
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 我可以使用什么来停止循环而不是"返回 0"?
- 我可以使用反向迭代器作为ForwardIt吗
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 我可以添加自定义 #pragma 规则吗?
- 当我可以打破混叠规则