将无限值分配给整数类型是否具有未定义的行为?

chq*_*lie 5 c floating-point type-conversion undefined-behavior language-lawyer

C 标准指定了有限浮点值在存储为整数类型时如何转换,但似乎没有指定非有限值的行为:

\n
\n

6.3.1.4 实数浮点和整数

\n

1\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 当标准浮点类型的有限值转换为除 之外的整数类型时bool,小数部分将被丢弃(即值被截断为零)。如果整数部分的值不能用整数类型表示,则行为未定义。

\n

2\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 当十进制浮点类型的有限值转换为 以外的整数类型时bool,小数部分将被丢弃(即值被截断为零)。如果整数部分的值不能用整数类型表示,则应引发“无效”浮点异常,并且转换结果未指定。

\n

3\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0当整数类型的值转换为标准浮点类型时,如果转换的值可以在新类型中精确表示,则该值不变。如果要转换的值在可以表示但无法精确表示的值范围内,则结果是最接近的较高或最接近的较低可表示值,以实现定义的方式选择。如果正在转换的值超出了可以表示的值范围,则行为未定义。某些隐式转换的结果可能会以比新类型所需的范围和精度更大的范围和精度表示(参见 6.3.1.8 和 6.8.6.4)。

\n

4\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0当整数类型的值转换为十进制浮点类型时,如果转换的值可以在新类型中精确表示,则该值不变。如果无法准确表示正在转换的值,则应根据 IEC 60559 中的规定正确舍入结果,并引发异常。

\n
\n

C 标准中其他地方是否指定或未定义该行为?

\n

Bri*_*ian 7

将浮点类型的无限值转换为整数类型是未定义的 C,不是因为标准规定了什么,而是因为它没有规定

C 标准中其他地方是否未定义该行为?

标准不需要将行为显式声明为“未定义”,因为它是未定义的。简单地不定义它就足够了。这正是未定义行为的定义。引用N3096/3.4.3

3.4.3
未定义的行为
在使用不可移植的或错误的程序结构或错误的数据时出现的行为,本文档对此没有强加要求

注意:正如Eric Postpischil 的回答中提到的,该标准还指出,明确标记为“未定义”的行为与省略任何定义的行为之间没有区别。两者都是同样未定义的行为。

该标准仅对浮点类型的有限值到整数类型的转换提出要求。标准未涵盖的每种情况本身都是未定义的行为。

为了额外保证,附件 J.2(未定义行为)下有以下条目:

在以下情况下,行为未定义:
...
(16) 与整数类型之间的转换会产生超出可表示范围的值 (6.3.1.4)。

由于无穷大确实超出了整数类型可以表示的范围,因此将无穷大转换为整数类型是未定义的。

  • @chqrlie:与神话相反,标准明确指出,指定一个操作调用 UB、完全忽略指定其行为或指定该操作不遵守的约束之间的重点没有区别。如果没有什么可以解释为指定行为,则无需明确说明某个操作调用 UB。 (2认同)

Eri*_*hil 5

C 2018 4 2 说:

\n
\n

如果违反出现在约束或运行时约束之外的 \xe2\x80\x9cshall\xe2\x80\x9d 或 \xe2\x80\x9cshall not\xe2\x80\x9d 要求,则行为未定义。未定义的行为在本文档中通过“未定义的行为”一词或通过省略任何明确的行为定义来指示。这三者的侧重点没有区别;它们都描述了未定义的\xe2\x80\x9c行为\xe2\x80\x9d。

\n
\n

由于将无限值转换为整数类型的行为没有明确的定义,因此它是未定义的行为。

\n