零数组的双精度数(使用memset(,0,))或含有双精度数的结构是否合法?
这个问题意味着两件事:
(1)从C标准的角度来看,这个UB不是吗?(在一个固定的平台上,这个UB怎么样......它只是浮动表示所有......)
(2)从实际角度来看:在intel平台上可以吗?(无论标准是什么).
Mat*_*lia 30
C99标准附件F说:
本附录规定了对IEC 60559浮点标准的 C语言支持.IEC 60559浮点标准特别适用于微处理器系统的二进制浮点算法,第二版(IEC 60559:1989),以前称为 IEC 559:1989和IEEE二进制浮点运算标准(ANSI/IEEE 754-1985) ).用于与基数无关的浮点运算的IEEE标准(ANSI/IEEE 854-1987)概括了二进制标准以消除对基数和字长的依赖性.IEC 60559通常是指浮点标准,如IEC 60559操作,IEC 60559格式等.定义的实现
__STDC_IEC_559__应符合本附录中的规范.如果指明了C语言与IEC 60559之间的绑定,则除非另有说明,否则IEC 60559指定的行为将被引用.
之后,
C浮动类型符合IEC 60559格式,如下所示:
- 该
float类型符合IEC 60559单一格式.- 该
double类型符合IEC 60559双格式.
因此,如果IEC 60559基本上是IEEE 754-1985,并且它指定8个零字节意味着0.0(如@David Heffernan所说),这意味着如果您发现已 __STDC_IEC_559__定义,则可以安全地进行0.0初始化memset.
Dav*_*nan 14
如果您正在谈论IEEE754,那么标准将+0.0定义为双精度为8个零字节.如果您知道自己受IEEE754浮点支持,那么这个定义很明确.
至于英特尔,我想不出在Intel x86/x64上不使用IEEE754的编译器.
即使您不太可能遇到出现问题的机器,但如果您确实像问题标题中所示那样谈论数组,并且如果这些数组在编译时的长度已知(即不是VLA),那么直接初始化它们可能会更方便:
double A[133] = { 0 };
Run Code Online (Sandbox Code Playgroud)
应该总是有效。如果稍后您必须再次将这样的数组归零,并且您的编译器符合现代 C (C99),您可以使用复合文字来完成此操作
memcpy(A, (double const[133]){ 0 }, 133*sizeof(double));
Run Code Online (Sandbox Code Playgroud)
在任何现代编译器上,这应该与 一样高效memset,但具有不依赖于 的特定编码的优点double。
David Heffernan对你问题的第(2)部分给出了一个很好的答案.第(1)部分:
在一般情况下,C99标准不保证浮点值的表示.§6.2.6.1说:
除非本条款中另有说明,否则所有类型的陈述均未指明.
......而且该子条款没有进一步提及浮点数.
你说:
(在一个固定的平台上,这个UB怎么样......它只是浮动表示所有......)
确实 - " 未定义的行为"," 未指定的行为"和" 实现定义的行为" 之间存在差异:
因此,由于浮点表示是未指定的行为,因此它可以从平台到平台以未记录的方式变化(其中"平台"在这里表示"硬件和编译器的组合"而不仅仅是"硬件").
(我不确定如何保证a double表示如此定义,即+0.0如果__STDC_IEC_559__定义了所有位零,如Matteo Italia的答案所述,实际上是在实践中.例如,GCC从未定义过这个,即使是使用许多硬件平台上的IEEE 754/IEC 60559.)
| 归档时间: |
|
| 查看次数: |
11772 次 |
| 最近记录: |