Comprehensive C99 support with visual studio

I would like to use complex numbers as defined in C99, but I need to support compilers that don't support it (MS compilers come to mind).

I don’t need many functions, and performing the necessary functions on compilers without support is not too complicated. But it’s hard for me to implement a β€œtype”. Ideally, I would like to do something like:

#ifndef HAVE_CREAL double creal(complex z) { /* .... */ } #endif #ifndef HAVE_CREALF float creal(float complex z) { /* ... */ } #endif 

But I'm not sure I see how to do this if the compiler cannot recognize the "float complex". I would actually think this is not possible, but the Dinkumware C library seems to point to something else. What is the solution? I am not against using functions / macros for type operations, but I need a way to assign values ​​to a complex number and return its real / imaginary part in a way that is compatible with C99.

Decision

I ended up doing something like this:

 #ifdef USE_C99_COMPLEX #include <complex.h> typedef complex my_complex; #else typedef struct { double x, y; } my_complex; #endif /* * Those unions are used to convert a pointer of my_complex to native C99 * complex or our own complex type indenpendently on whether C99 complex * support is available */ #ifdef USE_C99_COMPLEX typedef union { my_complex my_z; complex c99_z; } __complex_to_c99_cast; #else typedef union { my_complex my_z; my_complex c99_z; } __complex_to_c99_cast; #endif 

to determine the type and as follows to determine the set of complex functions:

 #ifndef HAVE_CREAL double my_creal(my_complex z) { union { my_complex z; double a[2]; } z1; z1.z = z; return z1.a[0]; } #endif #ifdef HAVE_CREAL my_complex my_creal(ny_complex z) { __complex_to_c99_cast z1; __complex_to_c99_cast ret; z1.my_z = z; ret.c99_z = creal(z1.c99_z); return ret.npy_z; } #endif 

It's a bit complicated, but it allows me to easily use C lib functions when they are available, and can be partially automated with a code generator.

+6
c c99 visual-studio complex-numbers
source share
2 answers

No matter what you do, you cannot correctly handle the "float complex" in a compiler other than C99. So instead of writing this, make a few typedef. This is much simpler if you need to support only one complex type, so I will just demonstrate it 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 should 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)` does not work in C89 mode in the above code, because the compiler does not know how to make 5 into complex. This is a difficult problem to fix in C without compiler support - you need to resort to tricks, such as the new `tgmath.h`, which are specific to the compiler.

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

Another option (as another poster pointed out) is to use C ++ `std :: complex` for compilers other than C99. It might be OK if you can wrap things in typedefs and `# ifdef`s. However, you will need either C ++ or C99.

+6
source share

There is a library that I found on the msdn website. Here is the link. http://msdn.microsoft.com/en-us/library/0352zzhd.aspx

I hope this helps.

-one
source share

All Articles