相关疑难解决方法(0)

不同的优化级别可以导致功能不同的代码吗?

我很好奇编译器在优化时的自由度.让我们将这个问题限制在GCC和C/C++(任何版本,任何标准版本):

是否有可能根据编译的优化级别编写行为不同的代码?

我想到的例子是在C++中的各种构造函数中打印不同的文本位,并根据副本是否被删除而获得差异(尽管我无法使这样的东西工作).

不允许计数时钟周期.如果你有一个非GCC编译器的例子,我也很好奇,但我无法检查它.C中的示例的奖励积分:-)

编辑:示例代码应该是标准兼容的,并且从一开始就不包含未定义的行为.

编辑2:已经有了一些很棒的答案!让我稍微了解一下:代码必须构成一个格式良好的程序并且符合标准,并且必须在每个优化级别编译为正确的,确定性的程序.(这不包括形状不规则的多线程代码中的竞争条件等.)我也理解浮点舍入可能会受到影响,但让我们对此进行折扣.

我只获得了800点声望,所以我认为我将在第一个完整的例子中赢得50点声望以符合这些条件的(精神); 25如果涉及滥用严格别名.(视某人向我展示如何向他人发送赏金.)

c c++ gcc compiler-optimization

44
推荐指数
6
解决办法
4456
查看次数

编译器是否允许消除无限循环?

可以优化编译器删除无限循环,这不会改变任何数据,如

while(1) 
  /* noop */;
Run Code Online (Sandbox Code Playgroud)

从分析编译器可以推导出的数据流图,这样的循环是"死代码"而没有任何副作用.

是否删除了C90/C99标准禁止的无限循环?

C90或C99标准是否允许编译器删除此类循环?

更新:"Microsoft C版本6.0基本上做了这个优化.",请参阅caf的链接.

label: goto label;
return 0;
Run Code Online (Sandbox Code Playgroud)

将转变为

return 0;
Run Code Online (Sandbox Code Playgroud)

c compiler-construction optimization standards infinite-loop

30
推荐指数
3
解决办法
5512
查看次数

如果它调用共享库,C++中的无限循环仍然是未定义的行为吗?

据说无限循环for(;;);是未定义的行为.


来自http://en.cppreference.com/w/cpp/language/memory_model

在有效的C++程序中,每个线程最终都会执行以下操作之一:

  • 终止
  • 调用I/O库函数
  • 读取或修改易失性对象
  • 执行原子操作或同步操作

没有执行任何这些可观察的行为,任何执行线程都不能永远执行.

请注意,这意味着具有无限递归或无限循环的程序(无论是作为for语句实现还是通过循环goto或其他方式)具有未定义的行为.


但是如果它在共享库中调用函数呢?

for(;;) sofunc();

该函数可以执行任何类型的阻塞I/O或抛出异常.

在这种情况下,编译器是否假定循环具有一些可观察的行为?

c++ infinite-loop undefined-behavior

12
推荐指数
1
解决办法
1673
查看次数

C++标准对堆栈溢出有什么看法?

我看了一下C++ 0x标准草案,据我所知,堆栈溢出没有任何内容.搜索"堆栈溢出"不会产生任何结果,并且搜索"堆栈"我只获得了堆栈展开和std :: stack的引用.这是否意味着没有符合C++标准的实现,因为当本地对象(例如巨大的本地数组)耗尽内存时,没有机制允许处理错误?

这个问题的答案表明,至少C标准没有提到堆栈溢出.

要使问题具体,请考虑此计划

// Program A
int identity(int a) {
  if (a == 0)
    return 0;
  char hugeArray[1024 * 1024 * 1024]; // 1 GB
  return identity(a - 1) + 1;
}
int main() {
  return f(1024 * 1024 * 1024);
}
Run Code Online (Sandbox Code Playgroud)

和这个程序

// program B
int main() {
  return 1024 * 1024 * 1024;
}
Run Code Online (Sandbox Code Playgroud)

我认为C++标准不允许任何C++实现在这两个程序上做一些明显不同的事情.实际上程序A不会在任何现代机器上运行,因为它在堆栈上分配了一个exabyte内存(想象一下该函数实际上使用了巨大的数组,因此编译器无法以静默方式将其删除而不会产生不良影响).C++标准是否允许程序A失败?

编辑:问题不在于标准是否应该定义堆栈溢出会发生什么,问题是它说什么,如果有的话.

c++ stack-overflow undefined-behavior

11
推荐指数
1
解决办法
387
查看次数