这是我对C ++中结构声明的第二次调查。 (第一个是here)但现在我遇到了this post。具体来说,我不确定为什么这在C中完全没问题,但在C ++中却没有。
typedef struct{
int one;
int two;
}myStruct;
struct myStruct; //forward declaration fails
void blah(myStruct* pStruct);
上面的代码在我的UCCntu框中使用GCC编译得很好。我之所以认为这是因为第一个myStruct
存在于普通命名空间中,其中函数,变量名称存在。第二个myStruct
位于标记命名空间中。当编译器在函数原型中看到myStruct*
时,它会在两个名称空间中搜索并在正常的namspace中找到myStruct
,并且该名称恰好是typedef
名称,因此它可以是有效类型符。第二个myStruct
可以在以后定义为程序员想要的任何内容。第一个未命名 myStruct
不会出现任何混淆/冲突,因为程序员必须使用struct myStruct
来引用第二个
但是在C ++中,根据linked question中的讨论,我的理解是第一个 typedef myStruct
像往常一样存在于普通命名空间中。第二个myStruct
也存在
普通的命名空间(C ++中没有特定的标记命名空间?)但可能会被其他标识符所掩盖。所以我的问题是为什么第一个myStruct
与第二个myStruct
相同的名称空间不会与第二个myStruct
相同?
在更一般的意义上,除了程序员使用C ++语言提供的命名空间工具引入的显式命名空间之外,是否有任何预定义的命名空间消除了标识符的使用(包括标签,标签,typedef名称,对象/ functino标识符)就像在C? (C在我的第一次调查中预先定义了4个名称空间)。我可以在C ++标准中找到这些名称所在的位置吗?
编辑:我似乎没有问清楚这个问题。我只想知道
1)哪些命名空间(如果语言中有这样的定义)是Lables,typedef名称,struct / union / enum的标签名称,普通函数,正常变量/对象名称属于哪些? (如果我错过任何其他类型的名字,请添加。)
2)为什么正常的函数名称,正常的变量名称阴影标记名称,而标记名称不能。
3)如果C ++中有任何子句指定名称空格,如C(Section 6.2.1)
答案 0 :(得分:3)
在C ++中,您无法使用struct myStruct
来引用已typedef
编辑的无标记结构。并且您无法定义不同的struct myStruct
,因为名称与typedef名称冲突。
如果添加标记,那么{C}和C ++中仅struct myStruct
和myStruct
都会引用类型:
typedef struct myStruct {
int one;
int two;
} myStruct;
这里C ++中没有冲突,因为名称只解析为一种类型,特殊规则允许这一点。 C ++标准7.1.3节包括以下规则:
在给定的非类范围中,
typedef
说明符可用于重新定义该范围中声明的任何类型的名称,以引用它已引用的类型。如果使用typedef指定器在给定范围内重新定义可以使用详细类型说明符引用的实体,则该实体可以继续由详细类型说明符或枚举或类名称引用分别在枚举或类别定义中。
在给定范围内,typedef说明符不得用于重新定义在该范围内声明的任何类型的名称,以引用不同的类型。
类似地,在给定范围内,类或枚举不应声明与在该范围内声明的typedef-name同名,并引用类或枚举本身以外的类型。
[注意:命名类类型或其cv限定版本的typedef-name也是类名(9.1)。 如果使用typedef-name来标识详细类型说明符的主题(7.1.6.3),类定义(第9节),构造函数声明(12.1)或析构函数声明(12.4),该程序格式错误。 - 结束说明]