在C11 (及以后的)整数常量表达式中,只有以下操作数:
浮动常量,是强制转换的直接操作数。
以下代码:
int a[ A > B ? 16 : 32 ];当A和B是浮动常数时,C中的浮动常量无效:
$ echo '#include "t576.h"' | clang -std=c11 -pedantic -Wall -Wextra -DA=1.0 -DB=2.0 -c -xc -
In file included from <stdin>:1:
./t576.h:1:5: warning: size of static array must be an integer constant expression [-Wpedantic]但在C++中有效:
$ echo '#include "t576.h"' | clang++ -std=c++11 -pedantic -Wall -Wextra -DA=1.0 -DB=2.0 -c -xc++ -
<nothing>这一要求的起源/理由是什么?
额外的问题:在未来的C标准修订版中,删除这一要求会有用吗?
发布于 2022-01-14 11:46:32
这一要求的起源/理由是什么?
这意味着C编译器不需要能够在编译器中执行浮点算法。在编译与编译器宿主平台不同的目标平台时,复制目标浮点操作的准确行为可能需要做大量工作。(尤其是在IEEE 754浮点算法标准被广泛采用之前。)
要在C程序中实现浮点语义,编译器只需将源代码中的常量转换为目标浮点格式,并获得整数部分(在强制转换中)。它不必能够对它们执行一般的算术运算。如果没有这一要求,编译器将不得不再现目标平台的浮点算术操作。因此,如果程序使用浮点算法,编译器就可以通过生成指令来执行该算法,而不必自己执行该算法。算术常量表达式也是如此,它可以用作初始化器:C标准并不严格要求编译器来计算初始化器的值。它可以生成指令,在程序开始运行时(用于静态对象的初始化)或需要时(用于自动对象的初始化)计算值。
相反,整数常量表达式可以用于编译器需要值的地方,例如位字段的宽度。因此,编译器必须能够计算值本身。如果要求它能够进行浮点算法来获得值,这将为编写一些编译器增加相当大的负担。
额外的问题:在将来的C标准修订版中,删除这个要求会有用吗?
删除它将为C程序编写人员提供一些使用额外常量表达式的机会,并将要求C编译器编写人员做更多的工作。这些东西的价值是主观的。
发布于 2022-01-14 11:43:49
理由是常识:他们不想让用户声明一个包含大约3.1415项的数组--数组大小显然需要是一个整数。
对于C中的许多操作符,通常的算术转换会在出现浮点操作数时将结果转换为浮点数。如果是?:,则不会发生这种情况,因为结果是第二个或第三个操作数。而且,>运算符总是返回int,因此它也不真正适用于那里。
如果您不像引用的整数常量表达式定义的那样,立即将浮点操作数转换为整数类型,那么它将变成一个算术常量表达式,这是一个更广泛的术语。
所以你可以这么做:
int a[ (int)1.0 > (int)2.0 ? 16 : 32 ]; // compliant但你不能这么做
int a[ 1.0 > 2.0 ? 16 : 32 ]; // not compliant考虑int a[ (int)1.0 > (int)2.0 ? 16.0 : 32 ]; (也不兼容)。在这里,条件总是计算为false。我们应该得到32,但由于?:的特殊隐式转换规则,第2和第3个操作数在通常的算术转换中是平衡的,因此我们最终得到了32.0类型的double。如果这反过来会导致一个浮点数字不能被精确地表示,我们就会得到一个浮点数组大小。
https://stackoverflow.com/questions/70709194
复制相似问题