Почему у нас есть два разных определения?
Неясно, но я предполагаю, что это потому, что Clang по-прежнему выдает предупреждение для x = x
, когда x
не инициализирован, но не для x = *(&(x))
. Почти при всех обстоятельствах *, в которых одно из этих выражений имеет четко определенное поведение, другое имеет такое же четко определенное поведение. При других обстоятельствах, например, когда значение x
является неопределенным или неопределенным, оба имеют неопределенное поведение, или поведение x = x
определено, и поведение x = *(&(x))
неопределено, поэтому последнее не дает никаких преимуществ.
По какой причине первый способ может оказаться недостаточным?
Поскольку поведение обоих не определено в тех случаях использования, для которых они, по-видимому, предназначены. Поэтому совсем не удивительно, что разные компиляторы обрабатывают их по-разному.
Первый способ недостаточен только для Clang или в некоторых других случаях?
Оба значение и поведение выражений undefined . Таким образом, в одном смысле нельзя с уверенностью заключить, что одного из них достаточно для чего-либо. В эмпирическом смысле того, использует ли тот или иной дурак определенные компиляторы, чтобы они не выдавали предупреждений о том, что они в противном случае будут, и, тем не менее, должен излучать, вполне вероятно, что были, есть и / или будут компиляторы которые обрабатывают неопределенное поведение, связанное с обоими этими выражениями, иначе, чем G CC и Clang.
* Исключение составляют случаи, когда x
объявляется с register
класс хранения, в этом случае второе выражение имеет неопределенное поведение независимо от того, имеет ли x
четко определенное значение.