了解相同范围内的声明

时间:2019-01-29 11:42:11

标签: c language-lawyer declaration definition

这是关于ISO C的语言律师问题。

我试图了解标准中声明的定义。我使用N1570。考虑以下情况:

案例1

int a;
extern int a; //compatible types, external linkage, well-defined behavior

案例2

extern int a;
int a; //well-defined behavior, external linkage, well-defined behavior

案例3

int a;
static int a; //6.2.2/6.9.2UB, linkage-disagreement

案例4

static int a;
extern int a; //6̶.̶2̶.̶2̶/̶6̶.̶9̶.̶2̶ ̶U̶B̶,̶ ̶l̶i̶n̶k̶a̶g̶e̶-̶d̶i̶s̶a̶g̶r̶e̶e̶m̶e̶n̶t̶
              //as @EricPostpischil mentioned in the comment
              //it is well-defined in 6.2.2

案例5

int a;
long a; //6.7.2 UB incompatible types

案例6

int a;
const int a; //6.7.2/6.7.3 incompatible types, different qualifiers

案例7

enum{
    a
};

enum{
    a //UB, why?
};

案例8

 enum {
     a
 };

 const unsigned char a; //UB, why?

案例1-4

该解释在标准中清晰明确。

6.2.2(p7)

  

如果在翻译单元中,相同的标识符同时出现在两个   内部和外部的联系,行为是不确定的。

案例5

6.2.7(p1)部分中进行了解释:

  

如果在翻译单元中,相同的标识符同时出现在两个   内部和外部的联系,行为是不确定的。

6.7(p4)

  

同一范围内的所有引用同一对象或对象的声明   函数应指定兼容的类型。

案例6

6.7.3(p10)解释:

  

要使两个合格的类型兼容,两个都应具有   兼容类型的完全相同的版本

案例7-8

不清楚。我没有在标准中找到任何与之相关的正式参考。 6.2.7(p1)声明:

  

对于两个枚举,对应的成员应具有相同的成员   值。

案例7满足该要求。

所以我看不到任何问题。

我没有发现与情况8明确相关的任何内容,因此,如果标准中未定义它,则应该是UB。

您能否在 案例7 案例8 的标准中找到解释?< / p>

2 个答案:

答案 0 :(得分:3)

案例7

6.7.2.3第1、4和5段(第137页)对此进行了说明(强调是我的)

  

1特定类型的内容最多定义一次。

     

4 结构,并集或枚举类型的所有声明   具有相同的范围,并使用相同的标签声明相同的类型。   不管是否有标签或其他什么声明   类型在同一个翻译单元中,类型不完整   [脚注129)],直到紧接在列表的大括号之后   定义内容,然后完成。

     

5 两个结构,联合或枚举类型的声明,   在不同的范围内或使用不同的标记声明不同的类型。   结构,联合或   不包含标记的枚举类型声明了不同的类型

因此,相同类型的枚举的一个例子[如果不用于第1段]就像

enum TagNameA
{
    a
};
enum TagNameA
{
   a
};

案例8 6.7.2.2第3段(第136页)对此做了解释(强调是我的)

  

枚举器列表中的标识符声明为常量,   具有int类型,并且可能出现在允许的任何位置[脚注:   127)]

     

...

     

[脚注127)] 因此,枚举常量的标识符   在同一范围内声明的声明应彼此不同,并且   来自普通声明符中声明的其他标识符。

案例8

const unsigned char a;

a普通声明符,它与枚举常量标识符 a 不相同。 / p>

答案 1 :(得分:0)

案例8

 enum {
     a
 };

 const unsigned char a; //UB, why?

不是UB。这是语义错误。 UB可能仅在运行时发生。

重复标识符“ a”。考虑

int b = a;  //which a? 

案例7

enum{
    a
};

enum{
    a //UB, why?
};

不是UB。这是语义错误。 UB可能仅在运行时发生。

重复标识符“ a”。考虑

int b = a;  //which a?