C99 complex support with visual studio

No matter what you do, you can't make "float complex" parse properly in a non-C99 compiler. So instead of writing that, make some typedefs. It's far easier if you only have to support one complex type, so I'll just demonstrate with float complex.

First, define the types:

#if __STDC_VERSION__ >= 199901L
//using a C99 compiler
#include <complex.h>
typedef float _Complex float_complex;
#else
typedef struct 
{
    float re, im;
} float_complex;
#endif

Then, we need to be able to create complex numbers, and emulate creal and cimag.

#if __STDC_VERSION__ >= 199901L
//creal, cimag already defined in complex.h

inline complex_float make_complex_float(float real, float imag)
{
   return real + imag * I;
}
#else
#define creal(z) ((z).re)
#define cimag(z) ((z).im)

extern const complex_float complex_i; //put in a translation unit somewhere
#define I complex_i
inline complex_float make_complex_float(float real, float imag)
{
    complex_float z = {real, imag};
    return z;
}
#endif

Next, write functions that wrap addition, subtraction, multiplication, division, and comparisons.

#if __STDC_VERSION__ >= 199901L
#define add_complex(a, b) ((a)+(b))
//similarly for other operations
#else //not C99
inline float_complex add_complex(float_complex a, float_complex b)
{
  float_complex z = {a.re + b.re, a.im + b.im};
  return z;
}
//similarly for subtract, multiply, divide, and comparison operations.

Note that add_complex(c, 5) doesn't work in C89 mode in the above code, because the compiler doesn't know how to make 5 into a complex. This is a tricky problem to fix in C without compiler support -- you have to resort to tricks like the new tgmath.h uses, which are compiler-specific.

Unfortunately, the effect of all of this is that the nice C99 syntax like a+b to add complex numbers has to be written add_complex(a, b).

Another option (as another poster pointed to) is to use C++ std::complex on non-C99 compilers. This might be OK if you can wrap things in typedefs and #ifdefs. However, you'd require either C++ or C99.