我收到了这个警告 . 我想定义行为,但我想保持这个代码的原样 . 什么时候可以打破别名规则?
警告:解除引用类型惩罚指针将破坏严格别名规则[-Wstrict-aliasing]
String是我自己的字符串,它是一个POD . 此代码从C调用.S可能是int . 字符串几乎是 struct String { RealString*s; }
但是模板和辅助函数 . 我做一个静态断言来确保String是一个pod,是4bytes,int是4bytes . 我还写了一个断言,检查所有指针是否> = NotAPtr . 它在我的新/ malloc重载 . 如果你建议的话,我也可以把这个断言放在String中
考虑到我遵循的规则(主要是字符串是一个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
}
}
4 回答
完全支持
memcpy
. 所以是对char*
的惩罚(例如,你可以使用std::copy
) .如果您不能将代码更改为2个函数,那么为什么不呢(要求C99编译器使用
uintptr_t
- 对于较旧的MSVC,您需要自己定义,2008/2010应该没问题):将变量视为两种不同类型的安全方法是将其转换为联合 . 联合的一部分可以是你的指针,另一部分是整数 .
标准规定了一组最小的操作,所有符合要求的实现必须以可预测的方式处理,除非它们遇到转换限制(因此所有的投注都是关闭的) . 它不会尝试定义实现必须支持的所有操作以适合任何特定目的 . 相反,对超出这些授权的行动的支持被视为执行质量问题 . 作者承认,实施可能符合要求,但质量很差,无用 .
像你这样的代码应该可用于低级编程的高质量实现,并以预期的方式表示内存中的内容 . 不应期望它可用于其他类型的实现,包括那些将“实施质量”问题解释为试图以低质量但符合要求的方式行事的邀请 .