首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在整数常量表达式中使用浮点算法是无效的?

为什么在整数常量表达式中使用浮点算法是无效的?
EN

Stack Overflow用户
提问于 2022-01-14 10:30:56
回答 2查看 252关注 0票数 1

在C11 (及以后的)整数常量表达式中,只有以下操作数:

浮动常量,是强制转换的直接操作数。

以下代码:

代码语言:javascript
复制
int a[ A > B ? 16 : 32 ];

AB是浮动常数时,C中的浮动常量无效:

代码语言:javascript
复制
$ 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++中有效:

代码语言:javascript
复制
$ echo '#include "t576.h"' | clang++ -std=c++11 -pedantic -Wall -Wextra -DA=1.0 -DB=2.0 -c -xc++ -
<nothing>

这一要求的起源/理由是什么?

额外的问题:在未来的C标准修订版中,删除这一要求会有用吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-14 11:46:32

这一要求的起源/理由是什么?

这意味着C编译器不需要能够在编译器中执行浮点算法。在编译与编译器宿主平台不同的目标平台时,复制目标浮点操作的准确行为可能需要做大量工作。(尤其是在IEEE 754浮点算法标准被广泛采用之前。)

要在C程序中实现浮点语义,编译器只需将源代码中的常量转换为目标浮点格式,并获得整数部分(在强制转换中)。它不必能够对它们执行一般的算术运算。如果没有这一要求,编译器将不得不再现目标平台的浮点算术操作。因此,如果程序使用浮点算法,编译器就可以通过生成指令来执行该算法,而不必自己执行该算法。算术常量表达式也是如此,它可以用作初始化器:C标准并不严格要求编译器来计算初始化器的值。它可以生成指令,在程序开始运行时(用于静态对象的初始化)或需要时(用于自动对象的初始化)计算值。

相反,整数常量表达式可以用于编译器需要值的地方,例如位字段的宽度。因此,编译器必须能够计算值本身。如果要求它能够进行浮点算法来获得值,这将为编写一些编译器增加相当大的负担。

额外的问题:在将来的C标准修订版中,删除这个要求会有用吗?

删除它将为C程序编写人员提供一些使用额外常量表达式的机会,并将要求C编译器编写人员做更多的工作。这些东西的价值是主观的。

票数 5
EN

Stack Overflow用户

发布于 2022-01-14 11:43:49

理由是常识:他们不想让用户声明一个包含大约3.1415项的数组--数组大小显然需要是一个整数。

对于C中的许多操作符,通常的算术转换会在出现浮点操作数时将结果转换为浮点数。如果是?:,则不会发生这种情况,因为结果是第二个或第三个操作数。而且,>运算符总是返回int,因此它也不真正适用于那里。

如果您不像引用的整数常量表达式定义的那样,立即将浮点操作数转换为整数类型,那么它将变成一个算术常量表达式,这是一个更广泛的术语。

所以你可以这么做:

代码语言:javascript
复制
int a[ (int)1.0 > (int)2.0 ? 16 : 32 ]; // compliant

但你不能这么做

代码语言:javascript
复制
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。如果这反过来会导致一个浮点数字不能被精确地表示,我们就会得到一个浮点数组大小。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70709194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档