🏷️C언어의 namespace(이름공간)
- 잘 알려져 있지 않지만, C언어도 C++처럼 namespace개념이 존재한다.
- 🖇️cf. C++
std::
처럼 명시적으로 사용하는 것은 아니다.
- 어떤 종류의 명칭(식별자)은 항상 특별한 문맥에서만 등장한다.
- 🔍ex) label명은
goto
키워드 뒤에만 나오거나, label명 뒤에 :
가 나오는 문맥에서만 등장한다.
- 번역 프로그램은 특정 명칭이 label을 위한 명칭인지 아니면, 그 외의 명칭인지 쉽게 구분할 수 있다.
- 확실히 구분되는 문맥에 따라 동일한 명칭을 공유할 수 있도록 허락해주면, 프로그래머가 더 많은 명칭을 사용할 수 있다.
- 이러한 까닭에, C는 네 종류의 namespace를 정의하고 있다.
- 서로 다른 namespace에 속해있는 명칭은 동일한 명칭일지라도 전혀 다른 개체를 지칭하는 명칭으로 취급된다.
📌1. label명
- label명은 항상
:
이 따라오거나 goto
키워드 뒤에만 나온다.
- 🔍ex) label명
foo
foo:
...
goto foo;
📌2. 구조체(struct), 공용체(union), 열거(enum)를 위한 tag명칭
- tag명칭은
struct
, union
, enum
키워드 뒤에만 등장한다.
- 🔍ex) tag명칭
foo
enum foo{APPLE, KIWI, GRAPE};
📌3. 구조체(struct), 공용체(union)의 member명
- 멤버명은 구조체나 공용체 선언 문맥이나, 두 멤버 지정 연산자(
.
or ->
)뒤에만 나온다.
- 🔍ex) 구조체의 member명
foo
struct tag
{
int foo;
} object;
...
object.foo;
📌4. 그 외
- 함수명, 대상체 명칭(변수명), 열거 상수명, typedef name은 모두 같은 namespace을 공유한다.
🏷️정리
- 즉, 다음과 같이 명칭이 중복되어도 namespace만 다르다면 전혀 문제가 없다.
- 🔍ex) 명칭 foo를 4가지의 다른 namespace에서 사용한 예시
int main(void)
{
struct foo
{
char foo;
} foo;
foo.foo = 'A';
goto foo;
printf("unreachable");
foo:
printf("%c", foo.foo);
return 0;
}
- 물론 가독성이 심각하게 좋지 못하기에 일부러 유지보수를 어렵게 하려는 목적이 아니라면, 당연히 지양해야 한다.