相关疑难解决方法(0)

未定义的行为和序列点

什么是"序列点"?

未定义的行为和序列点之间的关系是什么?

我经常使用有趣和复杂的表达方式a[++i] = i;,让自己感觉更好.我为什么要停止使用它们?

如果您已阅读此内容,请务必访问后续问题重新加载未定义的行为和序列点.

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ c++-faq undefined-behavior sequence-points

970
推荐指数
4
解决办法
10万
查看次数

为什么优化会破坏此功能?

我们最近在大学里开了一个关于多种语言编程特色的讲座.

讲师写下了以下功能:

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,这样编译器就不会触及它们,即使他认为它们永远不会被读或写,但我不知道为什么会发生这种情况.

c c++ optimization endianness strict-aliasing

49
推荐指数
3
解决办法
4343
查看次数

可以使用const变量避免混淆问题

我的公司使用消息服务器将消息const char*收集到a中,然后将其转换为消息类型.

在提出这个问题之后,我对此感到担忧.我不知道消息服务器中有任何不良行为.const变量是否可能不会出现锯齿问题?

例如,假设foo是以下列MessageServer方式之一定义的:

  1. 作为参数: void MessageServer(const char* foo)
  2. 或者作为顶部的const变量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)

c++ alias const strict-aliasing reinterpret-cast

6
推荐指数
1
解决办法
903
查看次数