Если значение неинициализированной переменной не должно влиять на значение выражения, это все еще UB? - PullRequest
8 голосов
/ 01 сентября 2011

Это продолжение обсуждения , которое, я думаю, заслуживает отдельного вопроса.

По сути, результат этого не определен?

int x;
int y = 1 || x;

Здесь есть два аргумента "здравого смысла":

  1. Математически говоря, независимо от значения x, значение y должно быть 1.
  2. Из-за короткого замыкания, x никогда не оценивается.

Но контраргумент в том, что у нас есть выражение, которое включает неинициализированную переменную, поэтому все ставки сняты (теоретически).

В более общем смысле, если значение неинициализированной переменной не может повлиять на результат выражения, это "безопасно"? e.g.:

int x;
int y = x - x;

Обычный отказ от ответственности: Конечно, я не сторонник написания подобного кода.

Ответы [ 4 ]

8 голосов
/ 01 сентября 2011

В C это неопределенное поведение - использовать значение объекта с автоматической продолжительностью хранения, пока оно не определено.(J.2, информативно), но для переменных с автоматической продолжительностью хранения можно хранить неопределенное значение.

В выражении может использоваться только его значение, если оно оценено и согласно 6.5.12 (логический оператор ИЛИ) второй операнд не оценивается (не говоря уже о том, чтобы его значение использовалось), если первый операнд сравнивается с неравенством 0.

6 голосов
/ 01 сентября 2011

Отказ от ответственности: Я думал, что вопрос был также о C ++.Видимо, это только для Си.Я не говорю на C-стандарте, но я полагаю, что мой ответ остается верным и для C, хотя использование другой терминологии

int x;
int y = 1 || x;

четко определено, потому что x просто не оценивается - гарантия короткого-схемная оценка ||.

int x;
int y = x - x;

вызывает неопределенный бевиор, потому что вычисляется x и происходит преобразование lvalue в rvalue .Если это преобразование не состоялось, поведение было бы четко определено, например:

int x;
int* y = &x;
int z = &x - &x;

Здесь x также оценивается, но преобразование lvalue-в-значение не происходит, поэтому оно определено.

2 голосов
/ 01 сентября 2011

Относительно y = x - x;, один из худших сценариев, который следует иметь в виду, состоит в том, что неинициализированная переменная может содержать значение прерывания.

Нельзя полагаться на наличие оптимизатора, чтобы понять, что x - x на самом деле не зависит от значения x, и поэтому, безусловно, реализации разрешено использовать значение x при оценке x - x, и оно используется в абстрактной машине.

Такесли это значение прерывания, у вас возникнет аппаратная ошибка или что-то еще, что делает реализация, когда оно прерывается.UB, в любом случае.

Я помню, что одна система, которую я использовал, добавила дополнительные гарантии о поведении неопределенных значений.Он заявил, что использование неопределенного значения не будет взрываться, но также не должно вести себя так, как если бы это было какое-либо действительное значение типа.Таким образом, x-x приведет к другому неопределенному значению, не обязательно к 0. Это на самом деле меньше полезнее, чем перехват, поскольку он сохраняет ошибку программирования для последующего использования, когда вы меньше всего этого ожидаете, но AFAIK это полностьюсоответствует, так как поведение не определено стандартом.

1 голос
/ 01 сентября 2011

По сути, результат этого не определен?

int x; int y = 1 || x;

Nopes! x никогда не используется / оценивается .

int y = x - x; вызывает UB.

...