C 언어 시큐어코딩 - Declare and Initialization 3
상충되는 Linkage 식별자를 선언하지 않는다.
Linkage는 동일한 범위 내에서 여러 영역으로 선언되거나 여러 번 선언된 식별자를 동일한 개체나 함수를 참조하도록 만들 수 있다. 식별자는 externally linked, Internally linked 또는 not llinked로 분류된다. 이 세 종류의 분류는 다음과 같은 특징을 갖는다.- External linkage: 프로그램에 속한 모든 편집 단위 및 라이브러리에서 동일한 객체 또는 기능을 나타낸다. 식별자는 링커에서 사용할 수 있다. External
- Internal linkage: 주어진 번역 단위 내에서 동일한 객체 또는 함수를 나타낸다. linker는 내부 링크가 있는 식별자에 대한 정보가 없다. 따라서 이러한 식별자는 번역 단위 내부에 있다.
- No linkage: 식별자에 연결이 없는 경우 식별자를 사용하는 추가 선언은 새로운 변수 또는 새로운 유형과 같은 새로운 것을 선언한다.
다음 표는 단일 변환 단위에서 두 번 선언된 객체에 할당된 연결을 나타낸다. 열은 첫 번째 선언, 행은 재 선언을 의미한다.
static (second) | no linkage (second) | extern (second) | |
---|---|---|---|
static (first) | internal | Undefined | Internal |
no linkage (first) | Undefined | No linkage | External |
extern (first) | Undefined | Undefined | External |
잘못된 코드 예제
이 예제에서i2
와 i5
는 내부와 외부 연결 모두 갖는 것으로 정의된다. 두 식별자 중 하나를 사용하면 정의되지 않은 동작이 발생하게 된다.int i1 = 10; /* Definition, external linkage */
static int i2 = 20; /* Definition, internal linkage */
extern int i3 = 30; /* Definition, external linkage */
int i4; /* Tentative definition, external linkage */
static int i5; /* Tentative definition, internal linkage */
int i1; /* Valid tentative definition */
int i2; /* Undefined, linkage disagreement with previous */
int i3; /* Valid tentative definition */
int i4; /* Valid tentative definition */
int i5; /* Undefined, linkage disagreement with previous */
int main(void) {
/* ... */
return 0;
}
상세 정보
Microsoft Visual Studio 2013은 가장 높은 진단 수준에서도 이 코드에 대한 경고를 표시하지 않는다.GCC 컴파일러는
i2
와 i5
의 충돌하는 정의에 치명적인 진단을 생성한다.올바른 코드 예제
이 예제에서는 상충되는 정의가 존재하지 않는다.int i1 = 10; /* Definition, external linkage */
static int i2 = 20; /* Definition, internal linkage */
extern int i3 = 30; /* Definition, external linkage */
int i4; /* Tentative definition, external linkage */
static int i5; /* Tentative definition, internal linkage */
int main(void) {
/* ... */
return 0;
}