C - 不同操作系统上complex.h中的意外行为

时间:2016-11-11 17:09:39

标签: c clang c99

请考虑以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));
   return EXIT_SUCCESS;
}

使用gcc -std=gnu99 -lm进行编译,我希望输出为

  

inf + 0 *我

     

0 + 0 *我

在Linux上是正确的(在使用gcc 4.4.7的Scientific Linux 6.8,使用gcc 5.3.1的Fedora 23和使用gcc 4.8.4的Ubuntu 14.04.5上测试)。

然而,在OS X(10.11.5 with clang-602.0.53)上,我得到了

  

inf + 0 *我

     

nan + nan * I

很明显,clang不符合C99标准(参见N1256,G.5.1节;严格来说,它仅仅是推荐的做法,而不是标准)。 实际上,clang没有定义宏__STDC_IEC_559_COMPLEX__,这在第2节中介绍。 G.1。 clang是否故意这样做? 更新:经过一些检查后,我发现我测试的几个Linux环境也没有定义这个宏,但代码仍能在那里正常工作。

目前,我的跨平台支持解决方法是检查宏

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
int main()
{
   complex double aaa = INFINITY + 0*I;
   printf("%.f + %.f*I\n", creal(aaa), cimag(aaa));
   complex double bbb = 1.0/aaa;
   #ifndef __STDC_IEC_559_COMPLEX__
   if(isnan(bbb)) 
   { 
      bbb = 0; //or do some trick that has to do with the problem context
   }
   #endif
   printf("%.f + %.f*I\n", creal(bbb), cimag(bbb));

   return EXIT_SUCCESS;
}   

但我不确定它是否健壮......有什么建议吗?

1 个答案:

答案 0 :(得分:1)

对于双参数,您使用%f而不是%lf。我认为这会导致不可预测的行为。