这是有效的 C99 代码吗?如果是这样,它是否定义了实现定义的行为?
int a;
unsigned long b[] = {(unsigned long)&a+1};
根据我对 C99 标准的理解,从 ISO C99 标准的 §6.6 开始,这可能是有效的:
整数常量表达式应具有整数类型,并且应仅具有整数常量的操作数 (...) 整数常量表达式中的强制转换运算符应仅将算术类型转换为整数类型,但作为 sizeof 运算符的操作数的一部分除外。
初始化器中的常量表达式允许更大的自由度。这样的常量表达式应为或评估为以下之一:
- 算术常数表达式,
- (...)
- 对象类型的地址常量加上或减去整数常量表达式。
但是,由于加法可能会溢出,这可能不会被视为常量表达式,因此不是有效的 C99 代码。
有人可以确认我的推理是否正确吗?
请注意,GCC 和 Clang 都接受此代码而不会发出警告,即使使用-std=c99 -pedantic
. 但是,当转换为unsigned int
而不是 时unsigned long
,即使用以下代码:
int a;
unsigned long b[] = {(unsigned int)&a+1};
然后两个编译器都抱怨该表达式不是编译时常量。