例如,编译器可以
> unwind loops和
>做constant folding.
这两个优化使代码执行速度更快,而不会影响原始源代码的完整性.没有这些优化运行的任何代码都将在启用它们的情况下运行.
但是,编译器优化也会影响代码逻辑.以下是我所知道的两个例子:
> Removing copy constructors and assignment operators来自临时工可能会消除可能的副作用.
>重新排列包含浮点值的算法可能会影响浮点错误(希望需要-ffast-math参数).
我很惊讶,很幸运,了解这些因为他们可能在错误的情况下成为巨大的潜在陷阱.
所以我想知道,有没有其他情况下c编译器优化会影响代码逻辑?我特意在g编译器下查找有关c 11(没有任何未定义的行为)的信息,但欢迎提供其他编译器的提示.
解决方法
An implementation is free to disregard any requirement of this
International Standard as long as the result is as if the requirement
had been obeyed,as far as can be determined from the observable
behavior of the program. For instance,an actual implementation need
not evaluate part of an expression if it can deduce that its value is
not used and that no side effects affecting the observable behavior of
the program are produced.
但是,标准提到了一个允许的优化,它打破了“as-if”规则:
When certain criteria are met,an implementation is allowed to omit
the copy/move construction of a class object,even if the copy/move
constructor and/or destructor for the object have side effects. In
such cases,the implementation treats the source and target of the
omitted copy/move operation as simply two different ways of referring
to the same object,and the destruction of that object occurs at the
later of the times when the two objects would have been destroyed
without the optimization.123 This elision of copy/move operations,
called copy elision,is permitted in the following circumstances
(which may be combined to eliminate multiple copies):— in a return
statement in a function with a class return type,when the expression
is the name of a non-volatile automatic object (other than a function
or catch-clause parameter) with the same cvunqualified type as the
function return type,the copy/move operation can be omitted by
constructing the automatic object directly into the function’s return
value— in a throw-expression,when the operand is the name of a
non-volatile automatic object (other than a function or catch-clause
parameter) whose scope does not extend beyond the end of the innermost
enclosing try-block (if there is one),the copy/move operation from
the operand to the exception object (15.1) can be omitted by
constructing the automatic object directly into the exception object—
when a temporary class object that has not been bound to a reference
(12.2) would be copied/moved to a class object with the same
cv-unqualified type,the copy/move operation can be omitted by
constructing the temporary object directly into the target of the
omitted copy/move— when the exception-declaration of an exception handler (Clause 15) declares an object of the same type (except for cv-qualification) as the exception object (15.1),the copy/move operation can be omitted by treating the exception-declaration as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the exception-declaration.