문제

나는 Main ()의 첫 번째 줄 이전에 일어나는 글로벌/정적 계급 멤버의 모든 초기화를 생각하는 데 익숙합니다. 그러나 최근에 표준이 표준으로 인해 초기화가 나중에 "모듈의 동적로드를 지원할 수 있도록"할 수 있다는 것을 읽었습니다. 동적 링크가있을 때 이것이 사실 인 것을 볼 수 있습니다. 라이브러리를 dlopen '하기 전에 라이브러리에서 초기화 된 글로벌이 초기화 될 것으로 기대하지 않을 것입니다. 그러나 정적으로 연결된 번역 단위 (내 앱의 Direct .O 파일) 그룹 내 에서이 동작이 직관적이지 않다는 것을 알게 될 것입니다. 동적으로 연결될 때만 게 날카롭게 발생합니까, 아니면 언제든지 발생할 수 있습니까? (또는 내가 틀린 것을 읽은 것입니까?;)

도움이 되었습니까?

해결책

표준은 3.6.2/3에서 다음과 같습니다.

네임 스페이스 범위의 객체의 동적 초기화 (8.5, 9.4, 12.1, 12.6.1)가 메인의 첫 번째 명령문 전에 수행되는지 여부는 구현되지 않습니다. 초기화가 메인의 첫 번째 명령문 후 어느 시점으로 연기되는 경우, 초기화 할 객체와 동일한 번역 장치에 정의 된 함수 또는 객체를 처음 사용하기 전에 발생합니다.

그러나 o 물론 당신은 할 수 공식적으로는 안됩니다 초기화가 언제 발생하는지 알려주십시오 변수에 액세스하기 전에 초기화가 발생하기 때문에! 다음과 같이 :

// t1.cc
#include <iostream>
int i1 = 0;

int main () {
  std::cout << i1 << std::endl

// t2.cc
extern int i1;
int i2 = ++i1;

나는 G ++ 4.2.4가 적어도 메인 이전에 'i2'의 초기화를 수행하는 것으로 보일 수 있습니다.

다른 팁

그 규칙으로 해결하고 싶었던 문제는 동적 하중의 것입니다. 수당은 동적 하중으로 제한되지 않으며 다른 경우에는 공식적으로 발생할 수 있습니다. 동적 로딩 이외의 다른 용도로 사용하는 구현을 모르겠습니다.

의사 코드를 검토합시다.

DLL :

static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }

응용 프로그램 :

static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;

정적 초기화에 따르면 AppVar2는 1+2 = 3을 얻습니다.

로컬 정적 변수에 적용 가능한 게으른 초기화 (DLL에 관계없이)

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}

나는 이것이 G ++ 4.7 및 CMake에서 내 경우에 일어난 일이라고 생각합니다 (이것이 CMAKE와 관련된 관련 세부 사항인지 확실하지 않음). 공장에 함수를 등록하는 코드가 있습니다. 전 세계적으로 초기화 된 변수에서 생성자 호출에 의존합니다.

이 코드가 있었을 때 정적으로 연결된 라이브러리 초기화는 발생하지 않았습니다! 직접 연결된 객체 파일로 옮겼을 때 (즉, 먼저 라이브러리에 결합되지 않음) 이제 잘 작동합니다.

그래서 나는 당신이 옳다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top