这是关于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>
答案 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)
enum {
a
};
const unsigned char a; //UB, why?
不是UB。这是语义错误。 UB可能仅在运行时发生。
重复标识符“ a”。考虑
int b = a; //which a?
enum{
a
};
enum{
a //UB, why?
};
不是UB。这是语义错误。 UB可能仅在运行时发生。
重复标识符“ a”。考虑
int b = a; //which a?