혼란스러운 유형 정의 문법 이해
다음 코드 스니펫을 고려합니다.
typedef int type;
int main()
{
type *type; // why is it allowed?
type *k ;// which type?
}
오류가 발생했습니다.'k' is not declared in this scope컴파일러가 구문 분석합니다.type *k의 type*그리고.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
'programing' 카테고리의 다른 글
| MariaDB Azure에서 표준 시간대를 어떻게 구성합니까? (0) | 2023.09.03 |
|---|---|
| 벡터를 char** C++로 변환 (0) | 2023.09.03 |
| Macos에서 Xampp를 10.1.36-MariaDB에서 10.2로 업데이트 (0) | 2023.09.03 |
| .replace 와 -replace in powershell의 차이점은 무엇입니까? (0) | 2023.09.03 |
| 크로스 작동과 아우터 작동 속도 차이 (0) | 2023.09.03 |