VC中的复杂双重

时间:2018-03-01 17:28:57

标签: c visual-c++ portability

我正在通过一些旧的跨平台C代码。代码使用了许多定义如下的变量:

complex double *cur; /* Amplitude of basis function */

这一行在OSX和iOS上编译得很好,但在VS中我得到两个错误:

invalid combination of type specifiers

出现在" double"。我怀疑这不是一个真正的错误,真正的问题是:

identifier _complex is undefined

出现在单词" complex"上。当我右键单击并获得定义时,我会按照我的预期转到math.h,并找到这个定义:

#ifndef _COMPLEX_DEFINED
    #define _COMPLEX_DEFINED

    struct _complex
    {
        double x, y; // real and imaginary parts
    };

    #if !__STDC__ && !defined __cplusplus
        // Non-ANSI name for compatibility
        #define complex _complex
    #endif
#endif

我不知道的是,如果此代码无法正常运行,它甚至会将complex识别为_complex的别名?

在这里谈论我发现this thread。它建议使用_Dcomplex中的complex.h来表示这些变量。那是对的吗?如果是,complex中的math.h是什么?

无论如何,这段代码必须是跨平台的。有没有办法可以#define这种方式在VS和其他系统上工作?

2 个答案:

答案 0 :(得分:0)

正如您在代码_complex中看到的那样structurecomplex_complex的宏定义(当C ++提供对complex类型的支持时)。

现在,当您撰写complex double *cur;时,它会扩展为_complex double *cur;。因此,VC ++编译器对*cur的类型感到困惑,即类型为complexdouble

要解决此问题(并保持代码与平台无关),请执行以下操作:

#ifdef __VCPP__
     _complex
#else
     complex double 
#endif    
   *cur; /* Amplitude of basis function */

注意:如果平台是Windows,请定义__VCPP__宏。

<强>更新: __STDC____cplusplus都是预先定义的。请参阅here for Standard predefined identifier by VS,预定义宏列表 由于定义了__STDC____cplusplus,因此宏条件#if !__STDC__ && !defined __cplusplus被评估为false。因此complex不可用。

要解决此问题,您可以使用_complex

答案 1 :(得分:0)

对于可移植性,一种方法是根据编译器定义其定义不同的类型。

自C99以来,复杂类型被指定为float _Complexdouble _Complexlong double _Complex。 “复杂类型是实现不需要支持的条件特征。” §6.2.511

如果使用不兼容的C99编译器编译代码,请使用其提供的复杂类型。

#ifndef MM_COMPLEX_DEFINED
  #ifdef __STDC_VERSION__
    #if __STDC_VERSION__ >= 199901L
      #if __STDC_NO_COMPLEX__ != 1
        #define MM_COMPLEX_DEFINED
        typedef double _Complex complex_double;
...

#ifndef MM_COMPLEX_DEFINED
  // Use macro processing as needed per other compilers
  #ifdef _MSC_VER 
    #define MM_COMPLEX_DEFINED
    typedef complex complex_double;
... 

#ifndef MM_COMPLEX_DEFINED
  ...

对于C99 / C11之外的可移植性,可能需要额外的代码来访问复杂类型的实部和虚部。可能使用复杂浮点类型的许多方面都需要包装函数。

请参阅
Compiling C code in Visual Studio 2013 with complex.h library
How to Detect if I'm Compiling Code With Visual Studio 2008?
Is there a preprocessor macro to detect C99 across platforms?
Where are C11 optional feature macros?