例如,我有这个结构
struct A {
float x;
float y;
float z;
};
Run Code Online (Sandbox Code Playgroud)
我可以这样做吗?A a; float* array = (float*)&a;
并使用as float数组?
此代码是否违反严格别名?
struct {int x;} a;
*(int*)&a = 3
Run Code Online (Sandbox Code Playgroud)
更抽象的是,只要原始读/写操作类型正确,在不同类型之间进行转换是否合法?
在各种3d数学代码库中,我有时会遇到这样的事情:
struct vec {
float x, y, z;
float& operator[](std::size_t i)
{
assert(i < 3);
return (&x)[i];
}
};
Run Code Online (Sandbox Code Playgroud)
其中,AFAIK是非法的,因为允许实现在成员之间虚假地添加填充,即使它们属于同一类型,但实际上没有人会这样做.
通过static_asserts 施加约束可以使这变得合法吗?
static_assert(sizeof(vec) == sizeof(float) * 3);
Run Code Online (Sandbox Code Playgroud)
即static_assert没有被触发意味着operator[]什么是预期的并且不会在运行时调用UB?
c++ strict-aliasing language-lawyer type-punning structure-packing
我的公司使用消息服务器将消息const char*收集到a中,然后将其转换为消息类型.
在提出这个问题之后,我对此感到担忧.我不知道消息服务器中有任何不良行为.const变量是否可能不会出现锯齿问题?
例如,假设foo是以下列MessageServer方式之一定义的:
void MessageServer(const char* foo)MessageServer:const char* foo = PopMessage();现在MessageServer是一个巨大的功能,但它从来没有指派任何事情foo在1点但是,MessageServer的逻辑foo 将被转换为所选择的消息类型.
auto bar = reinterpret_cast<const MessageJ*>(foo);
Run Code Online (Sandbox Code Playgroud)
bar 将仅从随后读取,但将广泛用于对象设置.
这里是否存在别名问题,或者foo只是初始化并且从未修改过的事实会保存我吗?
编辑:
Jarod42的回答中找到与从铸造没有问题const char*的MessageJ*,但我不知道这是有道理的.
我们知道这是非法的:
MessageX* foo = new MessageX;
const auto bar = reinterpret_cast<MessageJ*>(foo);
Run Code Online (Sandbox Code Playgroud)
我们是否以某种方式说这是合法的?
MessageX* foo = new MessageX;
const auto temp = reinterpret_cast<char*>(foo);
auto bar = reinterpret_cast<const MessageJ*>(temp); …Run Code Online (Sandbox Code Playgroud)