Почему это простое назначение undefined?
Я обновлял свое понимание инициализации значения по сравнению с инициализацией по умолчанию и натолкнулся на this:
struct C {
int x;
int y;
C () { }
};
int main () {
C c = C ();
}
По-видимому, это UB, потому что
В случае C() существует конструктор, способный инициализация элементов x и y, поэтому инициализация не происходит. Попытка скопировать C() в c приводит к поведению undefined.
Думаю, я понимаю, почему, но я не уверен. Может кто-нибудь прокомментировать?
Означает ли это, что это тоже UB?
int x; x = x;
Кстати, что касается инициализации значения, то гарантируется, что оно равно нулю?
int x = int ();
Ответы
Ответ 1
В вашем первом примере есть поведение undefined, потому что компилятор по умолчанию
созданный экземпляр копии будет делать копию по порядку, int
может иметь
значения захвата и считывание значения захвата для его копирования могут привести к
программа для сбоя.
На практике я не могу представить, что это когда-либо на самом деле грохотало; компилятор
почти наверняка оптимизирует копию, и даже если это не так, это
скорее всего, будет использовать специальную побитовую копию, которая будет копироваться без
проверка значений захвата. (В С++ вы гарантированно сможете
копировать байты.)
Во втором случае, опять же, поведение undefined. Хотя в этом случае,
у вас есть назначение, а не копирование, и компилятор
менее вероятно, чтобы оптимизировать его. (В вашем первом назначении нет заданий
пример, только копирование конструкции.)
Для третьего, да. Инициализатор с пустым parenthese (и no
пользовательский инициализатор по умолчанию переопределяет его) сначала выполняет нуль
инициализация (точно так же, как это происходит для переменных со статическим временем жизни).
Ответ 2
Я не думаю, что это на самом деле undefined behavior
, хотя значения в c
имеют unspecified values
. То есть поведение программы хорошо определено, пока вы не закончите использование этих неуказанных значений. Если вы их используете, например. в состоянии или для их печати результаты не определены. Тем не менее, я не думаю, что программе разрешено делать что-нибудь странное.
Что касается использования конструктора по умолчанию для встроенных типов, это гарантирует получение нулевого значения типа, т.е. 0
для целых чисел, 0.0
для типов с плавающей точкой и т.д. Это также распространяется на членов типы без конструктора. Когда есть какой-либо конструктор, вам нужно позаботиться о создании своих членов без конструктора самостоятельно.
Ответ 3
Нет. Что произойдет, большинство компиляторов оптимизируют настройку переменной out, но те, которые этого не делают, просто не изменят значение x. Это то же самое, что и следующий код:
int x = 0;
x = 0;
Это не то, что вторая строка не будет выполняться, она просто ничего не сделает.