Lookup and name spaces
C 프로그램에서 identifier 가 발견되면, 해당 identifier를 도입한 declaration 이면서 현재 scope 내에 있는 선언을 찾기 위한 조회가 수행됩니다. C는 이러한 identifier들이 서로 다른 범주에 속하는 경우, 즉 name space 라 불리는 경우 동일한 identifier에 대한 여러 선언이 동시에 scope 내에 존재하는 것을 허용합니다:
|
4)
전역 속성 이름 공간:
attribute tokens
은 표준에 의해 정의되거나 구현에서 정의된 속성 접두사들입니다.
5)
비표준 속성 이름: 속성 접두사 뒤에 오는 속성 이름들. 각 속성 접두사는 구현에서 정의하는 속성들을 위한 별도의 이름 공간을 가집니다.
|
(C23부터) |
조회 시점에서 식별자의 네임스페이스는 식별자가 사용되는 방식에 따라 결정됩니다:
|
4)
속성 지정자 내에서 직접 나타나는 식별자(
[
[
...
]
]
)는 전역 속성 이름 공간에서 조회됩니다.
5)
속성 접두사 뒤에 오는
::
토큰 뒤에 오는 식별자는 속성 접두사가 도입한 이름 공간에서 조회됩니다.
|
(C23부터) |
목차 |
참고 사항
매크로 의 이름은 의미 분석 이전에 전처리기에 의해 대체되므로 어떤 이름 공간에도 속하지 않습니다.
일반적으로 typedef 선언을 사용하여 struct/union/enum 이름을 일반 식별자의 네임스페이스에 주입하는 것이 일반적인 관행입니다:
struct A { }; // 태그 이름 공간에 이름 A를 도입 typedef struct A A; // 먼저, "struct" 뒤의 A에 대한 조회가 태그 이름 공간에서 하나를 찾음 // 그런 다음 일반 이름 공간에 이름 A를 도입 struct A* p; // OK, 이 A는 태그 이름 공간에서 조회됨 A* q; // OK, 이 A는 일반 이름 공간에서 조회됨
동일한 식별자가 두 개의 네임스페이스에서 사용되는 잘 알려진 예시는 POSIX 헤더
sys/stat.h
의 식별자
stat
입니다. 이것은 일반 식별자로 사용될 때는
함수를 지칭
하고, 태그로 사용될 때는
구조체를 나타냅니다
.
C++와 달리, 열거형 상수는 구조체 멤버가 아니며, 그들의 이름 공간은 일반 식별자의 이름 공간입니다. 또한 C에는 구조체 범위가 없기 때문에, 그들의 범위는 구조체 선언이 나타나는 범위입니다:
struct tagged_union { enum {INT, FLOAT, STRING} type; union { int integer; float floating_point; char *string; }; } tu; tu.type = INT; // C에서는 정상, C++에서는 오류
|
표준 속성, 속성 접두사 또는 비표준 속성 이름이 지원되지 않는 경우, 잘못된 속성 자체는 오류를 발생시키지 않고 무시됩니다. |
(since C23) |
예제
void foo (void) { return; } // 일반 네임스페이스, 파일 스코프 struct foo { // 태그 네임스페이스, 파일 스코프 int foo; // 이 struct foo에 대한 멤버 네임스페이스, 파일 스코프 enum bar { // 태그 네임스페이스, 파일 스코프 RED // 일반 네임스페이스, 파일 스코프 } bar; // 이 struct foo에 대한 멤버 네임스페이스, 파일 스코프 struct foo* p; // OK: 태그/파일 스코프 이름 "foo" 사용 }; enum bar x; // OK: 태그/파일 스코프 bar 사용 // int foo; // 오류: 일반 네임스페이스 foo가 이미 스코프에 있음 //union foo { int a, b; }; // 오류: 태그 네임스페이스 foo가 스코프에 있음 int main(void) { goto foo; // OK: 레이블 네임스페이스/함수 스코프에서 "foo" 사용 struct foo { // 태그 네임스페이스, 블록 스코프 (파일 스코프를 가림) enum bar x; // OK, 태그 네임스페이스/파일 스코프에서 "bar" 사용 }; typedef struct foo foo; // OK: 태그 네임스페이스/블록 스코프에서 foo 사용 // 블록 스코프 일반 foo 정의 (파일 스코프를 가림) (foo){.x=RED}; // 일반/블록 스코프 foo와 일반/파일 스코프 RED 사용 foo:; // 레이블 네임스페이스, 함수 스코프 }
참고문헌
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.2.3 식별자 네임스페이스 (p: 29-30)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.2.3 식별자 네임스페이스 (p: 37)
- C99 표준 (ISO/IEC 9899:1999):
-
- 6.2.3 식별자 네임스페이스 (p: 31)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 3.1.2.3 식별자 네임스페이스
참고 항목
|
C++ 문서
참조:
Name lookup
|