2016-11-08 11 views
4

Интересно, почему это C++ код действителен и не вызывает каких-либо ошибок:C++/Java переменная рекурсии инициализации

extern int B; 
int A = B; 
int B = A; 

int main() 
{ 
    printf("%d\n", B); 
    system("pause"); 
    return 0; 
} 

Во-первых, переменная A будет создана в некоторой адреса памяти, то его значение будет инициализируется из переменной B, но затем переменная B возвращается к инициализации ее значения из переменной A и т. д., ...
Итак, почему здесь нет бесконечной петли или какой-либо ошибки?
Программа по-прежнему работает нормально, а значение
Это справедливо для Java, а также:

class A { 
    static final int AA = B.BB; 
} 

class B { 
    static final int BB = A.AA; 
} 

Любой может объяснить эти вопросы для меня, спасибо!

+3

Будьте осторожны здесь. Даже если код может казаться похожим и * кажется * вести себя аналогичным образом, Java и C++ все еще очень разные языки и могут на самом деле вести себя по-разному для другого аналогичного кода. –

+0

Heck, это область, где C и C++ начинают отличаться. – MSalters

ответ

3

Я отвечаю за это на C++. Хотя история не может быть все, что отличается для Java

Это не бесконечный цикл, потому что все во время компиляции, а вот как:

  • Компилятор видит, что B объявлен как extern
  • компоновщик знает, что A должен быть установлен на значение любой B должно быть, когда она объявлена, поэтому установка значения A задерживается до гораздо позже
  • B наконец объявлен, но поскольку ему не присвоено значение, оно получает значение по умолчанию 0.
  • Компилятор окончательно разрешает значение A и может также установить его на 0.
  • компилятор компилирует программу и выход 0

Смотреть это answer для более подробной информации

+0

«B наконец объявлен, но поскольку ему не присвоено значение». Итак, означает ли это, что 'B' будет искать' A', но видит, что 'A' задерживается, ожидая чего-то другого, поэтому' B' игнорирует init из 'A' и устанавливает значение по умолчанию (0)? – phibao37

+1

@ user2447581 это будет подробно описано, как работает компилятор, но по существу, как только обнаружено, что значение 'B' ссылается на себя, тогда я считаю, что компилятор обнаружит цикл во внутреннем графе, который он использует, чтобы отслеживать, что переменные используются там, где и когда он это сделает, он нарушит цикл и использует значение по умолчанию 'B', которое' A' затем получает – smac89

+0

спасибо за ваше объяснение и ссылку ссылки – phibao37

4

С I'm не знакомы с C++, я могу только объяснить это вам на примере Java ,

Я думаю, что это могло бы объяснить вопрос:

class A { 
    static final int AA = B.BB; 
} 

class B { 
    static final int BB = A.AA; 
} 
  • A.AA инициализируется со значением 0

  • A.AA ищет B.BB

  • B. BB инициализируется со значением 0

  • B.BB ищет A. AA

  • В это время A.AA уже имеет нулевое значение (значение по умолчанию межд), так B.BB становится 0.

  • А.AA становится 0

+0

Переменные Java начинаются со значения по умолчанию и затем назначаются +1 –

+0

спасибо за ваше объяснение о Java (все-таки я не могу сделать 2 приема за 2 ответа, извините за это :)). – phibao37

+0

Итак, главный ключ заключается в том, что если переменная ('BB') ищет другую (' AA'), есть 2 случая: ** 1. ** _ если 'AA' не инициализирован_, он инициализирует эту переменную со значением по умолчанию, ища значение присваивания, если есть и назначить обратно на «BB». ** 2. ** _ если 'AA' уже инициализирован_, он вернет значение' AA', независимо от того, ищет ли 'AA' какой-то другой или нет – phibao37