programing

혼란스러운 유형 정의 문법 이해

mbctv 2023. 9. 3. 22:10
반응형

혼란스러운 유형 정의 문법 이해

다음 코드 스니펫을 고려합니다.

typedef int type;
int main()
{
   type *type; // why is it allowed?
   type *k ;// which type?
}

오류가 발생했습니다.'k' is not declared in this scope컴파일러가 구문 분석합니다.type *ktype*그리고.k이 문법은 매우 혼란스럽지 않나요?

왜?type *typeC++ 표준에 의해 허용됩니까?문법이 그렇게 말하니까요? 왜죠?

type *type; // why is it allowed?

C++11 3.3.2/1은 다음과 같습니다.

이름의 선언 지점은 완전한 선언자(8항) 직후 및 초기화자(있는 경우) 앞에 있습니다.

변수 이름 그서변이름은수래▁so.type형식 이름을 사용할 때까지 도입되지 않았습니다.type은 형식이사가유의미일다니입한능한용름은의 유일한 입니다.type선언하는 동안에.

type *k ;// which type?

로컬 변수 이름은 전역 유형 이름을 숨기므로 여기서 선택합니다.이는 C++11 3.3.10/1에 설명되어 있습니다.

중첩된 선언 영역 또는 파생 클래스에서 동일한 이름을 명시적으로 선언하여 이름을 숨길 수 있습니다.

이름인 화된식이름형정규,,::type물론 여전히 이용 가능합니다.

문제는 정확히 언제 변수 이름이 식별자로 정의되는지에 대한 것이며, 언어는 변수가 선언되는 코드의 지점 바로 뒤에 있다고 결정합니다.

typedef int type;
int main() {
   type t;   // type refers to ::type
   int       // type still refers to ::type
   type;     // variable declared, this shadows ::type
   type + 1; // type is a variable of type int.
}

다른 맥락에서도 유사한 규칙이 있으며, 식별자가 선언되는 시기를 결정하는 문제일 뿐입니다.클래스의 초기화 목록과 같은 다른 유사한 상황도 있습니다.

struct test {
   int x;          // declare member
   test( int x )   // declare parameter (shadows member)
   : x(            // refers to member (parameter is not legal here)
        x )        // refers to parameter
   {};
};

또는 멤버 함수의 정의에서 식별자의 범위에서:

struct test {
   typedef int type;
   type f( type );
};
test::type         // qualification required, the scope of the return type is
                   // at namespace level
test::f(
         type t )  // but the scope of arguments is the class, no qualification
                   // required.
{}

그 결정의 근거에 대해서는 말씀드릴 수 없지만 일관성 있고 간단합니다.

혼란스럽지만, 이것이 접근할 수 있는 유일한 방법입니다.type변수. 사할경을 사용하고 ,type수행할 수 있는 유형:

typedef int type;
int main() {
    type *type;
    ::type *k ;
    return 0;
} 

이러한 문법 괴물의 대부분은 C와의 역호환성에서 비롯됩니다.

C++ 의미가 아닌 변수/유형 네임스페이스에서 네임스페이스를 분리해야 하는 이유는 분명합니다.유형 이름으로 변수 네임스페이스를 오염시키지 않으면 typeef에서 코드가 잘리지 않습니다.

"employee"라는 이름의 변수를 가진 코드가 이미 있다고 가정합니다.변수와 typedef가 동일한 네임스페이스에 있는 경우 "typedefstruct {} memployee;"는 기존 코드를 위반하여 변수 이름을 변경해야 합니다(IDE 이전 날짜에는 더 문제가 있었습니다).그러나 네임스페이스를 공유하지 않으면 문제가 없으며 큰 코드 기반에서 형식 이름을 선택할 때 걱정할 문제가 하나 줄어듭니다.

프로그래머가 선언하는 변수의 이름을 선택할 때 유연성을 제공하기 때문에 허용된다고 생각합니다.C#에서 다음 유형과 동일한 이름의 속성을 선언할 수 있습니다.

//C# code
class Manager
{
   public Name Name {get;set;}
};

C#로 코딩하면 이 기능이 매우 유용합니다.이름을 선택할 수 있는 옵션이 더 많기 때문입니다.그렇지 않으면, 만약 내가 전화한 타입이 있다면.Name그러면 같은 이름의 속성을 만들 수 없습니다. 다른 이름을 선택해야 합니다.Name_,_Name,name,NAME기타 - 모든 것이 나에게 매력적이지 않습니다.


당신의 코드에 관해서는, 범위 내에서 (객체 선언 후) type),type이미 변수이므로 '유형'을 직접 참조할 수 없습니다.하지만 저는 이것이 표준에 따라 잘 컴파일되어야 한다고 생각합니다.

typedef int type;
int main()
{
   type *type; // why is it allowed?
   ::type *k ;// which type?
}

데모: http://ideone.com/chOov

언급URL : https://stackoverflow.com/questions/8489215/understanding-confusing-typedef-grammar

반응형