首页 文章

Typedef-name与C中的struct标记冲突

提问于
浏览
2

这是我对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 位于 Tag 名称空间中 . 当编译器在函数原型中看到 myStruct* 时,它会在两个名称空间中搜索并在正常的namspace中找到 myStruct ,并且该名称恰好是 typedef 名称,因此它可以是有效的类型说明符 . 第二个 myStruct 可以在以后定义为程序员想要的任何东西 . 由于程序员必须使用 struct myStruct 来引用第二个,因此不会与第一个 unnamed 混淆/冲突 .

但是在C中,根据linked question中的讨论,我的理解是第一个 typedef myStruct 像往常一样生活在正常的命名空间中 . 第二个 myStruct 也存在于普通命名空间中(C中没有特定的 tag 命名空间?)但是其他标识符可能会黯然失色 . 所以我的问题是为什么第一个 myStruct 与第二个 myStruct 阴影中的第二个 myStruct 相同?

在更一般的意义上,除了程序员使用C语言提供的命名空间工具引入的显式命名空间之外,是否有任何预定义的命名空间消除了标识符的使用(包括标签,标签,typedef名称,对象/ functino标识符)喜欢在C? (C在我的第一次调查中预先定义了4个名称空间) . 我可以在C标准中找到这些名称所在的位置吗?

EDIT :我似乎没有问清楚这个问题 . 我想知道的是

1)哪些命名空间(如果语言中有这样的定义)是Lables,typedef名称,struct / union / enum的标签名称,普通函数,正常变量/对象名称属于哪些? (如果我错过了任何其他类型的名字,请添加 . )

2)为什么正常的函数名称,正常的变量名称阴影标签名称,而标签名称不能 .

3)如果C中有任何子句指定了C中的名称空格(Section 6.2.1

1 回答

  • 3

    在C中,您不能使用 struct myStruct 来引用已经 typedef ed的无标记结构 . 并且您无法定义不同的 struct myStruct ,因为名称与typedef名称冲突 .

    如果添加标记,那么 struct myStructmyStruct 都将引用C和C中的类型:

    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来标识elaborated-type-specifier(7.1.6.3),类定义(Clause 9),构造函数声明(12.1)或析构函数声明(12.4)的主题,则该程序为病态的 . - 结束说明]

相关问题