[英]Why is it possible to declare a struct and a non-struct with the same name?
显然,
出于进入C的史前史的原因,可以在同一范围内声明具有相同名称的结构和非结构。 - ( Bjarne Stroustrup - C ++编程语言。第4版 )
例如:
struct Ambig {};
// the struct must be referred to with the prefix struct
void Ambig(struct Ambig* buf) {}
我只是好奇最初的原因是什么? 如果没有理解,它似乎是一个糟糕的语言设计的例子,它会引起歧义并且令人困惑。
正如您在Stroustrup的引用中所述,其原因是历史性的。 在C中,您必须始终在struct的名称前加上struct
; 结构的名称(如联合或枚举的名称)称为标记,并且与其他符号位于完全不同的名称空间中。 所以像:
struct stat
{
// ...
};
int stat( char const* filename, struct stat* buf );
是完全合法的。 (以上是Posix的一部分)。
在C ++中,类的名称(用class
, struct
或union
)或枚举与其他所有名称在同一名称空间中,与C语言不同,您可以编写如下内容:
struct MyClass {};
MyClass variableName;
这不合法C.在C中,第二行必须是:
struct MyClass variableName;
问题是C ++需要能够使用C中定义的接口(如上面的Posix接口)。 所以C ++定义了一些允许它的特殊规则:你可以给一个变量或一个函数和一个类名相同的类。 当你这样做时,变量或函数名称具有优先权,并隐藏类名,除了“详细的类型说明符”(即class
, struct
, union
或enum
,后跟符号),其中非类型名称在抬头。
它是这样的原因与继承自C的C ++有关。它没有“添加”到C ++,它就在那里,因为它在C中以这种方式工作。
在C中,你必须使用struct X
和union Y
(C中没有class
关键字),或者使用typedef struct XA;
然后使用名称A
而不是strcut X
(其中X和A可以是同一名称)。
在C ++中,只要名称是唯一的,编译器就会理解X
指的是struct X
您不必在名称前键入struct
, union
或class
,也不必使用typedef
创建新的独立名称。
由于C ++旨在允许(尽可能)使用C语法,因此在引用struct X
时仍允许编写struct X
这允许使用其他模糊的名称。
除非历史设计决定要求,否则强烈建议不要利用这种“可能性”,因为它将实现的更多是混乱......
我只是好奇最初的原因是什么? 如果没有理解,它似乎是一个糟糕的语言设计的例子,它会引起歧义并且令人困惑。
在C中,它是名称空间的第一个实现。 标识符存在于不同的名称空间中,并且如果它们在不同的名称空间中声明,则它们可以具有相同的名称。 结构标记和普通标识符的名称空间不是C中唯一的两个名称空间.C中有四个名称空间:
(C99,6.2.3标识符的名称空间p1)“因此,各种标识符类别有单独的名称空间,如下所示:
- 标签名称(通过标签声明和使用的语法消除歧义);
- 关键字struct,union或enum)的结构,联合和枚举的标记(通过跟随任何24)消除歧义;
- 结构或工会的成员; 每个结构或联合为其成员都有一个单独的名称空间(通过。或 - >运算符用于访问成员的表达式的类型消除歧义);
- 所有其他标识符,称为普通标识符(在普通声明符中声明或作为枚举常量)。“
在结构之前添加struct
是完全合法的C.因此一些C代码也适用于C ++。
你有什么期望? C ++基于C.
在C ++中,我们避免使用struct
每一个结构之前。 我从未真正在生产代码中看到它。
关于歧义,我认为没有人知道为什么他们允许这样做。 但我相信这是因为在添加struct
时解决了歧义。 你基本上告诉编译器这不是一个函数,因此消除了possible meaning
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.