ОК, моя вопиющая игра за награду, приведя конкретный пример. Я соберу биты из ответов других людей и моих комментариев.
В целях различного поведения на разных уровнях оптимизации, «уровень оптимизации A» будет обозначать gcc -O0
(я использую версию 4.3.4, но это не имеет большого значения, я думаю, что любая даже смутно недавняя версия будет покажите разницу, за которой я следую), а «уровень оптимизации B» будет обозначать gcc -O0 -fno-elide-constructors
.
Код прост:
#include <iostream>
struct Foo {
~Foo() { std::cout << "~Foo\n"; }
};
int main() {
Foo f = Foo();
}
Вывод на уровне оптимизации A:
~Foo
Вывод на уровне оптимизации B:
~Foo
~Foo
Код полностью допустим, но выходные данные зависят от реализации из-за elision конструктора копирования, и в частности он чувствителен к флагу оптимизации gcc, который отключает копирование ctor elision.
Обратите внимание, что, вообще говоря, «оптимизация» относится к преобразованиям компилятора, которые могут изменять поведение, которое не определено, не определено или определяется реализацией, но не поведение, определенное стандартом. Таким образом, любой пример, который удовлетворяет вашим критериям, обязательно является программой, выходные данные которой не определены или определены реализацией. В этом случае по стандарту не определено, будут ли удалены копирующие векторы, просто мне повезло, что GCC надежно удаляет их практически всегда, когда есть возможность, но имеет возможность отключить это.