>  기사  >  백엔드 개발  >  다른 번역 단위의 전역 변수가 C에서 예기치 않은 동작을 일으킬 수 있는 이유는 무엇입니까?

다른 번역 단위의 전역 변수가 C에서 예기치 않은 동작을 일으킬 수 있는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-10-30 02:51:28947검색

 Why Can Global Variables in Different Translation Units Lead to Unexpected Behavior in C  ?

C의 전역 초기화 순서 및 종속성 해결

C에서는 단일 번역 단위 내의 전역 변수가 정의된 순서대로 초기화됩니다. . 그러나 다양한 번역 단위에 걸쳐 전역 변수에 대해 잘 정의된 순서는 없습니다. 이러한 모호함으로 인해 다음 코드에 설명된 것처럼 예상치 못한 동작이 발생할 수 있습니다.

<code class="cpp">struct Foo {
    Foo() { printf("Foo::Foo()\n"); }
    void add() { printf("Foo::add()\n"); }
    static int addToGlobal() {
        printf("Foo::addToGlobal() START\n");
        globalFoo.add();
        printf("Foo::addToGlobal() END\n");
        return 0;
    }
};

Foo globalFoo;
int dummy = Foo::addToGlobal();</code>

globalFoo가 초기화되기 전에 addToGlobal이 호출되면 동작은 예상한 대로 나타납니다.

Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()

그러나 순서가 바뀌면 Foo의 생성자가 호출되지 않고 globalFoo는 addToGlobal:

Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()

에서 어떻게든 액세스할 수 있습니다. 이 동작은 전역 초기화 순서가 둘 사이의 종속성을 무시한다는 사실에 기인합니다. . 이 경우 더미는 globalFoo에 의존하지만 초기화 순서는 보장되지 않습니다.

globalFoo를 사용하기 전에 Foo의 생성자가 호출되는지 확인하기 위한 한 가지 해결책은 전역 인스턴스에 대한 정적 포인터를 만들고 테스트하는 것입니다. addToGlobal 내에서 null인지 여부입니다. null인 경우 동적 초기화 전에 전역 Foo가 생성됩니다.

위 내용은 다른 번역 단위의 전역 변수가 C에서 예기치 않은 동작을 일으킬 수 있는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.