什么是"序列点"?
未定义的行为和序列点之间的关系是什么?
我经常使用有趣和复杂的表达方式a[++i] = i;,让自己感觉更好.我为什么要停止使用它们?
如果您已阅读此内容,请务必访问后续问题重新加载未定义的行为和序列点.
(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)
我们最近在大学里开了一个关于多种语言编程特色的讲座.
讲师写下了以下功能:
inline u64 Swap_64(u64 x)
{
u64 tmp;
(*(u32*)&tmp) = Swap_32(*(((u32*)&x)+1));
(*(((u32*)&tmp)+1)) = Swap_32(*(u32*) &x);
return tmp;
}
Run Code Online (Sandbox Code Playgroud)
虽然我完全理解这在可读性方面也是非常差的风格,但他的主要观点是这部分代码在生产代码中运行良好,直到它们实现了高优化级别.然后,代码将什么都不做.
他说,变量的所有赋值tmp都将由编译器优化.但为什么会这样呢?
我知道有些情况下变量需要声明为volatile,这样编译器就不会触及它们,即使他认为它们永远不会被读或写,但我不知道为什么会发生这种情况.
我的公司使用消息服务器将消息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)