C 전역 초기화 순서: 종속성 탐색
C에서 번역 단위 내의 전역 변수는 일반적으로 선언된 순서대로 초기화됩니다. 그러나 여러 번역 단위에 걸쳐 초기화 순서를 고려할 때 혼란이 발생할 수 있습니다.
초기 문제 시나리오
다음 코드를 고려하세요.
<code class="cpp">struct Foo { Foo() { printf("Foo::Foo()\n"); } void add() { printf("Foo::add()\n"); } static int addToGlobal() { globalFoo.add(); return 0; } }; Foo globalFoo; int dummy = Foo::addToGlobal(); int main() { printf("main()\n"); return 0; }</code>
With 이 코드에서 예상되는 출력은 다음과 같습니다.
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
그러나 dummy 및 globalFoo의 선언과 초기화를 바꾸면 다른 출력이 발생합니다.
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
초기화 순서 및 종속성
이 동작은 전역 변수의 초기화 순서가 종속성을 무시함을 의미합니다. 이 경우 Foo::addToGlobal() 호출은 생성자가 호출되기 전에 Foo의 메서드에 액세스하려고 시도합니다.
해결책: 올바른 초기화 보장
dummy가 초기화되기 전에 Foo의 생성자가 호출되도록 하려면 동일한 변환 단위에서 dummy 앞에 globalFoo를 정의할 수 있습니다. 이렇게 하면 globalFoo가 먼저 초기화되어 addToGlobal()이 해당 메서드에 성공적으로 액세스할 수 있습니다.
대체 솔루션: 정적 초기화 가드
또는 정적 초기화를 도입할 수 있습니다. Foo::addToGlobal():
<code class="cpp">static Foo* pFoo = nullptr; if (pFoo == nullptr) { pFoo = &globalFoo; } pFoo->add();</code>
이 검사는 메소드에 액세스하기 전에 포인터 pFoo가 globalFoo로 초기화되도록 보장하여 globalFoo의 조기 사용을 효과적으로 방지합니다.
위 내용은 종속성이 있는 C에서 전역 변수의 적절한 초기화를 보장하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!