Почему этот код C компилируется?
#include <stdio.h>
int main() {
int c = c;
printf("c is %i\n", c);
return 0;
}
Я определяю целочисленную переменную под названием c
, и я присваиваю ее значение самому себе. Но как это можно скомпилировать? c
не был инициализирован, так как его значение можно присвоить самому себе? Когда я запускаю программу, я получаю c is 0
.
Я предполагаю, что компилятор генерирует код сборки, который присваивает пространство для переменной c
(когда компилятор встречает оператор int c
). Затем он принимает значение нежелательной почты в этом неинициализированном пространстве и присваивает его обратно c
. Это то, что происходит?
Ответы
Ответ 1
Я помню, цитируя это в предыдущем ответе, но я не могу найти его в данный момент.
С++ 03 §3.3.1/1:
Точка объявления для имени сразу после его полного объявления (раздел 8) и перед его инициализатором (если есть),...
Следовательно, переменная c может использоваться даже до части инициализатора.
Изменить: Извините, вы спросили о C конкретно; хотя я уверен, что там есть эквивалентная линия. Джеймс Макнеллис нашел это:
C99 §6.2.1/7: Любой идентификатор, который не является тегом структуры, объединения или перечисления, имеет область действия, которая начинается сразу после завершения его декларатора. " За декларатором следует инициализатор.
Ответ 2
Ваша догадка в точности верна. int c
помещает пространство в стек для переменной, которое затем считывается и переписывается для части c = c
(хотя компилятор может оптимизировать это). Ваш компилятор подталкивает значение как 0
, но это не гарантируется всегда.
Ответ 3
Поведение undefined для использования неинициализированного значения (§C99 J.2 "Значение объекта с автоматической продолжительностью хранения используется, когда оно
неопределенный "). Таким образом, все может произойти от носовых демонов до c = 0, , играя Nethack.
Ответ 4
c инициализирован!
Хотя это одна строка кода, она фактически инициализирует c сначала, а затем присваивает ей c. Вам просто повезло, что компилятор инициализирует с нуля для вас.
Ответ 5
Спецификация C не гарантирует, что переменные будут инициализированы до 0, 0.0, а не "или".
Это функция компиляторов, и вы никогда не должны заставлять это делать.
Я всегда устанавливаю свой IDE/Compiler для предупреждения об этом.