extern

8618 단어 C++

원문
 
1. 외부 변수 설명
 
현대 컴 파일 러 는 일반적으로 파일 에 따라 컴 파일 하 는 방식 을 사용 하기 때문에 컴 파일 할 때 각 파일 에서 정의 하 는 전역 변 수 는?
 
서로 투명 하 다. 즉, 컴 파일 할 때 전역 변수의 보 이 는 도 메 인 은 파일 내부 에 제한 된다.다음은 간단 한 예 를 들 겠 습 니 다.A. cpp 와 B. cpp 두 개의 간단 한 C + + 원본 파일 을 포함 하 는 프로젝트 를 만 듭 니 다.
 
//A.cpp  
  
int i;  
void main()  
{  
  
}  

 
//B.cpp  
int i; 

 
 
이 두 파일 은 매우 간단 합 니 다. A. cpp 에서 우 리 는 전역 변수 i 를 정 의 했 고 B 에서 도 전역 변수 i 를 정 의 했 습 니 다.우 리 는 A 와 B 를 각각 컴 파일 하여 정상적으로 컴 파일 할 수 있 지만 링크 를 진행 할 때 오류 가 발생 했 습 니 다. 오 류 는 다음 과 같 습 니 다.
 
Linking...  
B.obj : error LNK2005: "int i" (?i@@3HA) already defined in A.obj  
Debug/A.exe : fatal error LNK1169: one or more multiply defined symbols found  
Error executing link.exe.  
A.exe - 2 error(s), 0 warning(s)  

 
 
즉, 컴 파일 단계 에서 각 파일 에서 정 의 된 전역 변 수 는 서로 투명 하고 A 를 컴 파일 할 때 B 에서 도 i 를 정의 하 는 것 을 알 아차 리 지 못 하 며 B 를 컴 파일 할 때 A 에서 도 i 를 정의 하 는 것 을 알 아차 리 지 못 한 다 는 것 이다.그러나 링크 단계 에 이 르 러 각 파일 의 내용 을 하나 로 합 쳐 야 하기 때문에 일부 파일 에서 정 의 된 전역 변수 이름 이 같 으 면 이 럴 때 오류 가 발생 합 니 다. 즉, 위 에서 제시 한 중복 정의 오류 입 니 다.따라서 각 파일 에서 정의 하 는 전역 변수 이름 이 같 지 않 습 니 다. 
   링크 단계 에서 각 파일 의 내용 (실제 컴 파일 로 만들어 진 obj 파일) 은 합 쳐 졌 기 때문에 특정한 파일 에 정 의 된 전역 변 수 는 링크 가 완 료 된 후에 보 이 는 범 위 는 전체 프로그램 으로 확대 되 었 습 니 다.이렇게 되면 한 파일 에 정 의 된 전역 변 수 는 전체 프로그램의 어느 곳 에서 든 사용 할 수 있다. 예 를 들 어 A 파일 에 전역 변 수 를 정의 하면 B 파일 에 해당 변 수 를 사용 할 수 있어 야 한다.우리 의 프로그램 을 수정 하고 검증 합 니 다.
 
//A.cpp  
  
void main()  
{  
    i = 100; //    B          
}  

 
//B.cpp  
int i;  

 
 
 컴 파일 결 과 는 다음 과 같다.
 
Compiling...  
A.cpp  
C:/Documents and Settings/wangjian/  /try extern/A.cpp(5) : error C2065: 'i' : undeclared identifier  
Error executing cl.exe.  
A.obj - 1 error(s), 0 warning(s)  

 
 
컴 파일 오류.
 
       사실 이 오류 가 발생 한 것 은 예상 한 것 입 니 다. 파일 에서 정의 하 는 전역 변수의 가시 성 이 전체 프로그램 으로 확 장 된 것 은 링크 가 완 료 된 후에 컴 파일 단계 에서 그들의 가시 성 은 각자 의 파일 에 국한 되 기 때 문 입 니 다.
 
       컴 파 일 러 의 안목 이 길지 않 아서 컴 파 일 러 는 특정한 변수 기호 가 이 파일 에서 정 의 된 것 이 아니 지만 다른 파일 에서 정 의 된 것 일 수도 있다 는 것 을 의식 하지 못 했다.
 
       비록 컴 파 일 러 는 멀리 볼 수 없 지만, 우 리 는 그것 에 게 위 에서 발생 한 문 제 를 해결 할 수 있 도록 힌트 를 줄 수 있다.이것 이 바로 extern 의 역할 이다.
 
       extern 의 원 리 는 매우 간단 합 니 다. 바로 컴 파일 러 에 게 알려 주 는 것 입 니 다. "현재 컴 파일 된 파일 에 식별 자가 있 습 니 다. 이 파일 에서 정의 되 지 않 았 지만 다른 파일 에서 정의 하 는 전역 변수 입 니 다. 놓 아 주 십시오!"
 
       우 리 는 위의 오류 프로그램 에 extern 키 워드 를 추가 합 니 다.
 
//A.cpp  
  
extern int i;  
void main()  
{  
    i = 100; //    B          
}  

 
//B.cpp  
int i;  

 
 
컴 파일, 링크 를 순조롭게 통과 하 다.
 
2. C + + 파일 에서 C 방식 으로 컴 파일 된 함수 호출
 
       C 방식 컴 파일 과 C + 방식 컴 파일
 
   C 에 비해 C + + 에 리 셋 과 같은 새로운 기능 이 추가 되 었 습 니 다. 그들의 컴 파일 에 있어 중요 한 차이 가 있 을 것 입 니 다.우 리 는 아래 의 작은 프로그램 을 각각 C 와 C + + 방식 으로 컴 파일 하여 두 가지 컴 파일 방식 의 차 이 를 연구한다.
int i;  
  
int func(int t)  
{  
    return 0;  
}  
  
void main()  
{  

}  

 
C 로 컴 파일 한 결과:
COMM     _i  :  DWORD  
PUBLIC    _func  
PUBLIC    _main  

C + + 방식 으로 컴 파일 한 결과:
PUBLIC    ?i@@3HA                                               ; i  
PUBLIC    ?func@@YAHH@Z                                         ; func  
PUBLIC    _main  

 
이 를 통 해 알 수 있 듯 이 C 방식 으로 컴 파일 하면 변수 이름과 함수 이름 이 통일 되 기 전에 밑줄 이 하나 더 붙 었 고 C + 컴 파일 후의 결 과 는 복잡 하 다. i 는?i @ @ 3HA, func 가?func@@YAHH@Z。C + + 의 이러한 복잡 해 보 이 는 명명 규칙 은 C + + 의 함수 리 셋, 파라미터 검사 등 특성 서 비 스 를 위 한 것 입 니 다. 
   다 중 파일 프로그램의 함수 호출
 
       일반적으로 프로젝트 의 파일 은 CPP 파일 (헤더 파일) 입 니 다.다음 프로그램 은 두 개의 파일 만 포함 합 니 다: A. CPP 와 B. CPP:
//A.CPP  
  
void func();  
void main()  
{  
    func();  
}  

 
//B.CPP  
void func()  
{  
  
}  

 
 
    프로그램의 구 조 는 다음 과 같 습 니 다. 파일 B. CPP 에서 함수 void func () 를 정 의 했 습 니 다. main 함 수 는 파일 A. CPP 에 있 고 main 함수 에서 B 에서 정의 하 는 함수 func () 를 호출 했 습 니 다.
 
       A 에서 B 에서 정 의 된 함 수 를 호출 하려 면 이 함수 의 성명 을 추가 해 야 합 니 다.이 예 에서 void func () 와 같이;함수 func () 에 대한 성명 입 니 다.
성명 이 없 으 면 A. CPP 를 컴 파일 할 때 오류 가 발생 합 니 다.컴 파일 러 의 시선 은 컴 파일 된 파일 에 만 국한 되 기 때문에 함수 성명 을 추가 하여 컴 파일 러 에 게 알려 야 합 니 다. "어떤 함 수 는 다른 파일 에 정의 되 어 있 습 니 다. 놓 아 주 셔 야 합 니 다!" 라 는 점 은 외부 전역 변 수 를 extern 으로 설명 하 는 것 과 같 습 니 다.
       주의해 야 할 것 은 일반적인 프로그램 은 헤더 파일 을 포함 하여 함수 의 성명 을 완성 하 는 것 이다.이 예 를 들 어 헤더 파일 B. H 를 만 들 고 헤더 파일 에 성명 문 void func () 를 추가 합 니 다.또한 A. CPP 에 포함 문 구 를 추가 합 니 다: \ # include "B. H".
       C + + 프로그램 에서 헤더 파일 의 기능 은 함수 성명 에서 클래스 로 확 장 됩 니 다.
    서로 다른 컴 파일 방식 에서 의 함수 호출
 
       만약 프로젝트 에서 CPP 파일 뿐만 아니 라 C 방식 으로 컴 파일 된 C 파일 도 있다 면 함수 호출 은 약간의 미묘 한 점 이 있 을 것 이다.우 리 는 B. CPP 를 B. C 로 바 꿉 니 다.
//A.CPP  
  
void func();  
  
void main()  
{  
    func();  
}  

 
//B.C  
  
void func()  
{
  
}  

 
A. CPP 와 B. C 를 각각 컴 파일 해도 문제 가 없 지만 링크 에 오류 가 발생 했 습 니 다.
Linking...  
A.obj : error LNK2001: unresolved external symbol "void __cdecl func(void)" (?func@@YAXXZ)  
Debug/A.exe : fatal error LNK1120: 1 unresolved externals  
Error executing link.exe.  
A.exe - 2 error(s), 0 warning(s)  

 
그 이 유 는 서로 다른 컴 파일 방식 으로 인 한 충돌 때문이다.파일 A 에 대해 서 는 C + + 방식 으로 컴 파일 되 었 으 며, 그 중의 func () 호출 은 컴 파일 되 었 습 니 다.
call    ?func1@@YAXXZ 

 
B 파일 도 C + + 방식 으로 컴 파일 된다 면 B 의 func 함수 이름 도 컴 파일 러 로 바 뀔 수 있 습 니까?func 1 @ @ YAXXZ, 그러면 아무 문제 없습니다.
       그러나 현재 B 파일 은 C 방식 으로 컴 파일 되 었 고 B 의 func 함수 이름 은 로 바 뀌 었 습 니 다.func, 이렇게 되면 A 중의 call?func1 @ @ YaXXZ 이 함수 호출 은 행방 이 없습니다. 링크 기 에서 볼 때 B 파일 에 이름 이 없 기 때 문 입 니까?func1 @ @ YaXXZ 의 함수 입 니 다.
       사실은 우리 프로그래머 들 은 B 파일 에 A 에서 호출 된 func 함수 의 정의 가 있다 는 것 을 알 고 있 습 니 다. 단지 C 방식 으로 컴 파일 되 었 기 때문에 이름 이 로 바 뀌 었 습 니 다.func。따라서 우 리 는 어떤 방식 으로 컴 파일 러 에 게 알려 야 한다. "B 에서 정 의 된 함수 func () 는 컴 파일 된 후에 func 로 명명 되 었 습 니 다. 아 닙 니 다. func 1 @ YaXXZ 는 call func 를 통 해 호출 되 어야 합 니 다. call? func 1 @ YaXXZ 가 아 닙 니 다." 쉽게 말 하면 컴 파일 러 에 게 호출 된 func () 함 수 는 C 방식 으로 컴 파일 되 었 습 니 다. fun ().문 구 는 콜 로 컴 파일 되 어야 합 니 다.func;콜 이 아니 라?func1@@YAXXZ。 
       우 리 는 extern 키 워드 를 통 해 컴 파일 러 가 위 에서 언급 한 문 제 를 해결 하 는 데 도움 을 줄 수 있다.
       이 예 에 대해 A. CPP 를 다음 과 같이 바 꾸 면 됩 니 다.
//A.CPP  
  
extern "C"  
{  
    void func();  
}  
  
void main()  
{  
    func();  
}  

 어 셈 블 리 코드 를 살 펴 보고 이때 func () 를 발견 합 니 다.문 구 는 콜 로 컴 파일 되 었 습 니 다.func。
 
3. 보충
2 와 마찬가지 로 C, C + + 혼합 프로 그래 밍 의 경우 다음 프로그램 을 고려 합 니 다.
//A.CPP  
   
extern int i;  
  
void main()  
{  
    i = 100;  
}  

 
//B.C  
  
int i; 

 
프로그램 은 매우 간단 합 니 다. 파일 B. C 에서 전역 변수 i 를 정 의 했 고 A. CPP 에서 이 전역 변 수 를 사 용 했 습 니 다.컴 파일 에 문제 가 없 지만 링크 에 오류 가 발생 했 습 니 다:
Linking...  
A.obj : error LNK2001: unresolved external symbol "int i" (?i@@3HA)  
Debug/A.exe : fatal error LNK1120: 1 unresolved externals  
Error executing link.exe.  
A.exe - 2 error(s), 0 warning(s)  

 
C 방식 으로 컴 파일 된 i 가 로 바 뀌 었 기 때 문 입 니 다.i, C + + 방식 에서 i 는?i@@3HA。 그래서 우 리 는 extern int i 만 사용한다.설명 하기 에는 아직 부족 합 니 다. 컴 파일 러 에 게 전역 변수 i 는 C 방식 으로 컴 파일 되 었 고 이름 이 로 바 뀔 것 이 라 고 알려 야 합 니 다.i, 아니?i@@3HA。
 
       우 리 는 A. CPP 를 다음 과 같이 수정 합 니 다.
//A.CPP  
  
extern "C"  
{  
   int i; 
}  
  
void main()  
{  
    i = 100;  
}  

 
프로그램 은 정상적으로 컴 파일 과 링크 를 통과 합 니 다. 우 리 는 어 셈 블 리 코드 를 살 펴 보고 문장 i = 100 을 발견 합 니 다.mov 로 컴 파일 되 었 습 니 다. DWORD PTR _i, 100。
 

좋은 웹페이지 즐겨찾기