itsource

C 네임스페이스 이해

mycopycode 2023. 9. 24. 12:48
반응형

C 네임스페이스 이해

여기서 인용하자면,

C에는 구조/연합/엔넘 태그 이름의 네임스페이스와 유형 ef 이름의 네임스페이스라는 두 가지 다른 유형의 네임스페이스가 있습니다.

name.c

$ cat name.c
#include<stdio.h>

typedef long long long2;

int long2 () {
    return 4;
}

int main() {

    printf("hello, world!");
    return 0;
}
$ gcc name.c -o name
name.c:4: error: 'long2' redeclared as different kind of symbol
name.c:3: error: previous declaration of 'long2' was here
$

이름2.c

$ cat name2.c
#include<stdio.h>

int four() {
    return 4;
}

struct dummy {
    int member;
};

int main() {

    struct dummy four;
}

$ gcc name2.c -o name2
$ 

C 네임스페이스 충돌을 이해하려고 합니다.

  • 첫 번째 경우, 왜 갈등이 발생합니까?함수도 typedef 네임스페이스에 속합니까?

  • 두 번째 경우에는 왜 갈등이 전혀 없는 것일까요?함수와 변수 모두 4로 명명됩니다.왜 컴파일러가 그걸 허용하는 거지?어떻게 있다.&four해결해야 할 문제입니까?

C에는 식별자를 위한 네 개의 다른 이름 공간이 있습니다.

  • ())goto자).
  • 태그(구조, 조합 및 열거형 이름).
  • 구조 및 유니언의 구성원(구조/유니온마다 별도의 네임스페이스가 있음).
  • 다른 모든 식별자(함수 이름, 개체 이름, 유형(def) 이름, 열거 상수 등).

C99 6.2.3 참조.

따라서 두 가지 질문에 다음과 같이 대답할 수 있습니다.

  1. 예, 함수 이름과 typedef 이름은 같은 이름 공간을 공유합니다.
  2. 컴파일러는 함수 또는 개체 이름에 대한 범위 규칙을 사용하므로 충돌이 없습니다.메인의 식별자는 글로벌 함수 이름에 음영을 주는 것으로 알려지는데, 경고 수준을 충분히 높게 설정하면 컴파일러가 경고합니다.

하지만 예제의 중요한 점은 네임스페이스가 아니라 이름의 범위입니다.

이름은.c, 둘다long2는 "ordinary 식별자"(동일한 네임스페이스를 공유함)이며, 둘 다 동일한 범위에서 정의되므로 충돌이 발생합니다.(C99 § 6.7/3)

이름이 2.c인 경우, 로컬 변수four 더 .four, 따라서 변수가 함수를 숨깁니다.four(C99 § 6.2.1/4).

두 번째 예제에는 "충돌 없음"이 표시되지 않습니다.충돌이 발생했습니다!시도해 보기:

#include <stdio.h>
int four(void) { return 4; }
struct dummy { int member; };
int main(void) {
    struct dummy four;
    four.member = four();
}

그리고 이젠 이 일.

#include <stdio.h>
int four(void) { return 4; }
struct dummy { int member; };
int main(void) {
    int (*fx)(void) = four; /* "save" function */
    struct dummy four;     /* hide it         */
    four.member = fx();    /* use "hidden" fx */
}

four 함수를 숨깁니다.four().

당신의 두 가지 질문에 빠르게 대답하기 위해서입니다.

Q1. 첫 번째 경우, 왜 갈등이 생기나요?함수도 typedef 네임스페이스에 속합니까?

A1. 예. 함수typedef'ed 유형의 식별자는 동일한 네임스페이스를 공유합니다.그래서 갈등이 있습니다.

Q2. 두 번째 경우, 갈등이 전혀 없는 이유는?함수와 변수 모두 4로 명명됩니다.왜 컴파일러가 그걸 허용하는 거지?&4는 어떻게 해결해야 합니까?

A2. 당신의 두 번째 예에서는 4라는 이름의 식별자가 같은 식별자 nameapse에 속하더라도 충돌이 없습니다.Ordinary namespace. 메인의 변수 식별자 4는 함수 범위에 있는 반면, 함수 식별자 4파일 범위에 있기 때문입니다.따라서 후자는 전자가 기본적인 범위 규칙으로 숨겨야 합니다.아래와 같이 파일 범위(global)로 변수 4를 이동하면 오류가 발생합니다.

...

struct dummy four; // Error! there's a previous definition
                   // in this file scope(global).

int main() {
    // struct dummy four; // Commented out.
}

실제로는 Label(라벨), Tag(태그), Member(멤버), Ordinary(보통)의 네 가지 식별자 네임스페이스가 있습니다.자세한 내용은 https://en.cppreference.com/w/c/language/name_space 에서 확인할 수 있습니다.

언급URL : https://stackoverflow.com/questions/3793952/understanding-c-namespaces

반응형