【发布时间】:2020-11-23 22:50:23
【问题描述】:
这些函数是将浮点数拆分为整数部分和小数部分。如果我不想写整数部分,将 NULL 传递给第二个参数是否安全?
【问题讨论】:
-
通常,对于标准函数,如果没有明确说明,传递NULL作为指向输出缓冲区的指针就是UB。
-
@EugeneSh。那好吧
标签: c math null floating-point undefined-behavior
这些函数是将浮点数拆分为整数部分和小数部分。如果我不想写整数部分,将 NULL 传递给第二个参数是否安全?
【问题讨论】:
标签: c math null floating-point undefined-behavior
C 2018 7.12.6.12 2 说“......它们将整数部分(以浮点格式)存储在 iptr 指向的对象中。” iptr 为 null 没有例外,因此我们可以得出结论,iptr 必须指向一个对象(不能为 null)。
此外,可选的附件 F 说“modf 的行为就像由以下人员实现一样”:
#include <math.h>
#include <fenv.h>
#pragma STDC FENV_ACCESS ON
double modf(double value, double *iptr) {
int save_round = fegetround();
fesetround(FE_TOWARDZERO);
*iptr = nearbyint(value);
fesetround(save_round);
return copysign(
isinf(value) ? 0.0:
value - (*iptr), value);
}
这里我们看到一个明确的存储到*ptr,没有检查空值。这适用于当实现支持附件 F(IEC 60559 浮点算法,实际上是 IEEE 754)时,但它确认了上述对 7.12.6.12 的解释,因为如果 modf 仅在附件 F 允许空参数的情况下才允许使用空参数,那就太奇怪了没有被采纳。
【讨论】:
它不安全。 C 标准没有提到该参数允许使用 NULL。
事实上,尝试将第二个参数设置为 NULL 会导致 CentOS 7 出现段错误。
【讨论】: