cl:编译时间与 运行 时间:inf 与 -nan(ind)
cl: compile time vs. run time: inf vs. -nan(ind)
示例代码(t50.c
):
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>
#include <float.h>
#include <assert.h>
const float d1 = NAN;
const float d2 = -0x0p+0;
const float d3 = NAN / -0x0p+0;
typedef union { uint32_t u; float d; } u_t;
int main(void)
{
u_t u1;
u_t u2;
u_t u3;
u1.d = *(volatile float*)&d1 / *(volatile float*)&d2;
u2.d = d3;
u3.d = d1 / d2;
if ( u1.u != u2.u || u1.u != u3.u )
{
printf("error:\n");
printf("u1 (run time) %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d);
printf("u2 (compile time) %08"PRIx32" %.*e\n", u2.u, DECIMAL_DIG, u2.d);
printf("u3 %08"PRIx32" %.*e\n", u3.u, DECIMAL_DIG, u3.d);
}
return 0;
}
编译器调用:cl t50.c /O1 /fp:precise && t50
预期结果:<nothing>
实际结果(cl x86
和 cl x64
相同):
error:
u1 (run time) ffc00000 -nan(ind)
u2 (compile time) 7f800000 inf
u3 ffc00000 -nan(ind)
我已指定 /fp:strict
:cl t50.c /O1 /fp:strict && t50
,但得到:
t50.c(8): error C2099: initializer is not a constant
t50.c(10): error C2099: initializer is not a constant
cl
版本:19.25.28611 for x86
和 19.25.28611 for x64
.
与gcc
(10.2.0) 和clang
(11.0.0) 比较:
gcc t50.c -O2 && a.exe
<nothing>
clang t50.c -O2 && a.exe
<nothing>
为什么?我在这里缺少什么?
标准 (C / IEEE) 怎么说?
UPD1:
if ( u1.d != u2.d || u1.d != u3.d )
的相同结果。
- 相同的结果
w/o unions
(即使用 float u1, u2, u3
)。
UPD2:
- 编译器的 NAN 定义:
Windows Kits\Include.0.18362.0\ucrt\corecrt_math.h
:#define NAN ((float)(INFINITY * 0.0F))
.
u1.d = NAN; printf("NAN %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d);
的输出(对于 cl x86
和 cl x64
):NAN ffc00000 -nan(ind)
.
Why?
cl
不遵循 IEEE-754 关于 NAN
.
What I'm missing here?
假设兼容的 C 编译器遵循 IEEE。
What the standard C says?
C 在 NAN
部门的规范松懈。我认为编译器是合规的,只是关于 NAN
.
的实施质量较差
What the standard IEEE says?
Non-compliant.
示例代码(t50.c
):
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>
#include <float.h>
#include <assert.h>
const float d1 = NAN;
const float d2 = -0x0p+0;
const float d3 = NAN / -0x0p+0;
typedef union { uint32_t u; float d; } u_t;
int main(void)
{
u_t u1;
u_t u2;
u_t u3;
u1.d = *(volatile float*)&d1 / *(volatile float*)&d2;
u2.d = d3;
u3.d = d1 / d2;
if ( u1.u != u2.u || u1.u != u3.u )
{
printf("error:\n");
printf("u1 (run time) %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d);
printf("u2 (compile time) %08"PRIx32" %.*e\n", u2.u, DECIMAL_DIG, u2.d);
printf("u3 %08"PRIx32" %.*e\n", u3.u, DECIMAL_DIG, u3.d);
}
return 0;
}
编译器调用:cl t50.c /O1 /fp:precise && t50
预期结果:<nothing>
实际结果(cl x86
和 cl x64
相同):
error:
u1 (run time) ffc00000 -nan(ind)
u2 (compile time) 7f800000 inf
u3 ffc00000 -nan(ind)
我已指定 /fp:strict
:cl t50.c /O1 /fp:strict && t50
,但得到:
t50.c(8): error C2099: initializer is not a constant
t50.c(10): error C2099: initializer is not a constant
cl
版本:19.25.28611 for x86
和 19.25.28611 for x64
.
与gcc
(10.2.0) 和clang
(11.0.0) 比较:
gcc t50.c -O2 && a.exe
<nothing>
clang t50.c -O2 && a.exe
<nothing>
为什么?我在这里缺少什么? 标准 (C / IEEE) 怎么说?
UPD1:
if ( u1.d != u2.d || u1.d != u3.d )
的相同结果。- 相同的结果
w/o unions
(即使用float u1, u2, u3
)。
UPD2:
- 编译器的 NAN 定义:
Windows Kits\Include.0.18362.0\ucrt\corecrt_math.h
:#define NAN ((float)(INFINITY * 0.0F))
. u1.d = NAN; printf("NAN %08"PRIx32" %.*e\n", u1.u, DECIMAL_DIG, u1.d);
的输出(对于cl x86
和cl x64
):NAN ffc00000 -nan(ind)
.
Why?
cl
不遵循 IEEE-754 关于 NAN
.
What I'm missing here?
假设兼容的 C 编译器遵循 IEEE。
What the standard C says?
C 在 NAN
部门的规范松懈。我认为编译器是合规的,只是关于 NAN
.
What the standard IEEE says?
Non-compliant.