编译以下C代码(使用MSVC):
char * const p1;
char * const p2;
static size_t sz = p2 - p1;
导致sz定义出现“初始化程序不是常数”错误。
由于指针是const(也尝试过数组,同样的错误),为什么diff指针不是恒定的?
根据C 2018 6.6 7,对于初始化程序中使用的常量,C标准仅要求实现支持完整对象类型加或减整数常量表达式的算术常量表达式,空指针常量,地址常量或地址常量。这些都不包括两个地址的减法,如下面的定义所示。
AC实现可能能够解决两个相同类型的符号地址的减法问题,尤其是如果编译器可以看到将它们放置在同一程序段中,并且C标准允许实现就可以这样做。但是,该标准不需要C实现来支持这一点,这至少部分是因为两个符号的减法可能涉及各种困难。一种是两个符号可能引用不同程序段中的对象,例如一个在恒定的只读段中,而另一个在未初始化的数据段中。编译器无法知道这些部分之间的相对差异,因为它取决于链接到程序中的其他对象模块的贡献,对象模块格式可能不支持将这种差异表示为链接器要解决的任何方式。即使在一个区域内,某些对象模块和符号方案也可以使链接器重新排列内容,以优化对齐问题。
根据6.6 8:
一个算术常量表达式应具有算术类型和应仅具有是积分常数,浮点常量,枚举常数,字符常数,操作数
sizeof
表达式,其结果是积分常数,和_Alignof
表达式。算术常数表达式中的强制转换运算符只能将算术类型转换为算术类型,除非作为操作数的一部分sizeof
或或_Alignof
。
根据6.6 9:
一个地址常量是一个空指针,一个指向一个左值指定静态存储持续时间,或指针的功能指示符的对象; 它应使用一元运算
&
符或强制转换为指针类型的整数常量显式创建,或通过使用数组或函数类型的表达式隐式创建。数组下标[]
和成员访问.
与->
运算符,地址&
和间接*
一元运算符以及指针强制转换可用于创建地址常量,但是不得使用这些运算符来访问对象的值。
根据6.3.2.3 3:
值为0的整数常量表达式或转换为类型的表达式
void *
称为空指针常量。…
根据6.6 6:
一个整数常量表达式应具有整数型和应仅具有是积分常数,枚举常数,字符常数,sizeof表达式其结果是积分常数,操作数
_Alignof
的表达式,和浮动常量是铸件的立即操作数。整数常量表达式中的强制转换运算符只能将算术类型转换为整数类型,除非作为sizeof
or_Alignof
运算符的一部分。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句