繁体   English   中英

为什么可以声明一个具有相同名称的结构和非结构?

[英]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 ++中,类的名称(用classstructunion )或枚举与其他所有名称在同一名称空间中,与C语言不同,您可以编写如下内容:

struct MyClass {};
MyClass variableName;

这不合法C.在C中,第二行必须是:

struct MyClass variableName;

问题是C ++需要能够使用C中定义的接口(如上面的Posix接口)。 所以C ++定义了一些允许它的特殊规则:你可以给一个变量或一个函数和一个类名相同的类。 当你这样做时,变量或函数名称具有优先权,并隐藏类名,除了“详细的类型说明符”(即classstructunionenum ,后跟符号),其中非类型名称在抬头。

它是这样的原因与继承自C的C ++有关。它没有“添加”到C ++,它就在那里,因为它在C中以这种方式工作。

在C中,你必须使用struct Xunion Y (C中没有class关键字),或者使用typedef struct XA; 然后使用名称A而不是strcut X (其中X和A可以是同一名称)。

在C ++中,只要名称是唯一的,编译器就会理解X指的是struct X 您不必在名称前键入structunionclass ,也不必使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM