Вызывает ли оптимизация возвращаемого значения неопределенное поведение?

Читая эту статью в Википедии, один из ответивших указал на следующий вопрос:

Конструктор копирования C++, временные объекты и семантика копирования

Я наткнулся на эту строку

В зависимости от компилятора и настроек компилятора результирующая программа может отображать любой из следующих выходных данных:

Разве это не квалифицируется как неопределенное поведение? Я знаю, что в статье написано Depending on the compiler and settings, но я просто хочу прояснить это.


person Aaron S    schedule 24.02.2010    source источник
comment
Есть определение, определяемое реализацией, в котором разработчик компилятора должен документировать поведение, а здесь не указано, что означает, что компилятор может делать все, что захочет, пока наблюдаемое поведение остается прежним. Тогда есть неопределенное поведение, что означает, что вы вошли в состояние в программе, где ее выполнение больше не определено. RVO — это случай, когда наблюдаемое поведение может измениться.   -  person GManNickG    schedule 24.02.2010


Ответы (4)


Нет, это не неопределенное поведение. Неопределенное поведение имеет конкретное определение в стандарте (в основном: «поведение, которое может возникнуть при использовании ошибочной программной конструкции или ошибочных данных, для которых настоящий международный стандарт не налагает требований»). В этом случае поведение не указано, но не неопределенный.

Разница в том, что любое выполнение чего-либо с неопределенным поведением делает все поведение вашей программы неопределенным (т.е. может случиться что угодно). С этим конкретным неопределенным поведением может произойти только одно из двух: либо конструктор копирования выполняется, либо нет.

person Jerry Coffin    schedule 24.02.2010
comment
Помню, я был совершенно сбит с толку, когда начал между: неопределенный, неопределенный и определяемый реализацией. Очень хорошее и краткое объяснение. - person Matthieu M.; 24.02.2010

Нет. Поведение определяется как один из выходов в списке. Неопределенное поведение включает демонов, вылетающих из вашего носа.

См.: Носовые демоны

person janm    schedule 24.02.2010

неопределенное поведение сильно отличается от определяемое реализацией поведение, о чем здесь идет речь.

person Alex Martelli    schedule 24.02.2010
comment
На самом деле это не определено реализацией - для этого потребуется, чтобы реализация документировала происходящее, что в данном случае не требуется. - person Jerry Coffin; 24.02.2010

Зависит от того, что вы подразумеваете под неопределенным. Я верю тому, что здесь говорили другие - по определению использования стандартного документа. Но я также знаю, что когда кто-то говорит «либо то, либо это, я не говорю вам, что именно», я думаю об этом как о неопределенном поведении.

Это не имеет большого значения, так как это никогда не должно вызывать ошибки. Когда вы определяете определенные методы, вы должны определять их в соответствии с определенными соглашениями — это своего рода неявный контракт между вами, компилятором и людьми, которые будут использовать и поддерживать ваш код.

В этом случае, независимо от того, получаете ли вы копию-конструкцию и т. д. или оптимизированное поведение, ожидается, что эффект будет одинаковым — вызывающая сторона получает желаемое значение. Если ваш конструктор копирования печатает "Hello World!" или имеет другие неуместные побочные эффекты, он не реализует ожидаемое поведение конструктора, поэтому вина за нарушение контракта лежит на вас.

person Steve314    schedule 24.02.2010
comment
+1 за сообщение о побочных эффектах, которые могут не выполняться автоматически из-за этой оптимизации :) Если это оператор печати, который вы с нетерпением ожидаете на терминале, вы можете его поймать; в то время как что-то более тихое, скажем, передача сообщения другому объекту, когда происходит строительство, не произойдет, и его будет трудно поймать. - person legends2k; 24.02.2010
comment
Итак, могу ли я сделать из этого вывод, что независимо от типа конструктора (будь то конструктор по умолчанию, копирование и т. д.) я не должен делать ничего конкретного, кроме инициализации членов? - person legends2k; 24.02.2010
comment
@legends2k: Да. Стандарт позволяет игнорировать вызовы конструктора копирования при возврате из функций, что означает, что ваш код не должен пытаться полагаться на побочные эффекты в конструкторах копирования. - person UncleBens; 24.02.2010
comment
Не правда. Он не должен делать ничего, кроме создания объекта, что не совсем одно и то же. Например, объект может владеть данными, которые находятся в каком-то внешнем контейнере, например. пользовательское выделение. Является ли это изменение побочным эффектом? Строго да, но на практике может и нет. Тем не менее, трудно выразить условия - субъективно речь идет о разделении что и как, но это нормально, если приложение позволяет пользователю сообщать/настраивать некоторые из того, как как часть чего. Да, я думаю, что это абсолютно определенно, может быть, возможно, так оно и есть. Частично. Возможно. Прозрачный? - person Steve314; 24.02.2010