C언어의 namespace

MySprtlty·2023년 2월 8일
1

C

목록 보기
12/37

🏷️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 /*tag명칭 foo*/
    {
    	char foo; /*member명 foo*/
    } foo; /*대상체 명칭 foo*/
    
    foo.foo = 'A'; /*대상체 명칭 foo와 member명 foo*/
    
    goto foo; /*label명*/    
    printf("unreachable");
    
foo: /*label명*/
	printf("%c", foo.foo); /*대상체 명칭 foo와 member명 foo*/
    
    return 0;
}
  • 물론 가독성이 심각하게 좋지 못하기에 일부러 유지보수를 어렵게 하려는 목적이 아니라면, 당연히 지양해야 한다.

0개의 댓글