Подтвердить что ты не робот

Почему это простое назначение 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 ();
4b9b3361

Ответ 1

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

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

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

Для третьего, да. Инициализатор с пустым parenthese (и no пользовательский инициализатор по умолчанию переопределяет его) сначала выполняет нуль инициализация (точно так же, как это происходит для переменных со статическим временем жизни).

Ответ 2

Я не думаю, что это на самом деле undefined behavior, хотя значения в c имеют unspecified values. То есть поведение программы хорошо определено, пока вы не закончите использование этих неуказанных значений. Если вы их используете, например. в состоянии или для их печати результаты не определены. Тем не менее, я не думаю, что программе разрешено делать что-нибудь странное.

Что касается использования конструктора по умолчанию для встроенных типов, это гарантирует получение нулевого значения типа, т.е. 0 для целых чисел, 0.0 для типов с плавающей точкой и т.д. Это также распространяется на членов типы без конструктора. Когда есть какой-либо конструктор, вам нужно позаботиться о создании своих членов без конструктора самостоятельно.

Ответ 3

Нет. Что произойдет, большинство компиляторов оптимизируют настройку переменной out, но те, которые этого не делают, просто не изменят значение x. Это то же самое, что и следующий код:

int x = 0;
x = 0;

Это не то, что вторая строка не будет выполняться, она просто ничего не сделает.