C Complex Numbers in C++?
The following code compiles and runs just fine in C (at least according to 'gcc -std=gnu99'), but it fails to compile under C++, giving "line 5: error: cannot convert 'double' to 'double complex' in initialization". Does anybody know why?
#include "/usr/include/complex.h"
#include <stdio.h>
int main(int argc, char * argv[]) {
double complex a = 3; // ERROR ON THIS LINE
printf("%lf\n", creal(a));
return 0;
}
I realize there is another way of doing complex numbers in C++, but I have to use C complex numbers in C++, because that is how the legacy code I was given does things. Thanks if you can help!
A C++ compiler could choose to support the _Complex
keyword as an extension (and a few do), but that isn't portable. If you want to have a portable C++ solution, you need to use the C++ std::complex templates, unfortunately.
The good news is that C++ std::complex numbers are guaranteed to be compatible with C complex numbers (in the sense that a pointer to one can always be converted to a pointer to the other, and the right thing will happen), which means that if you need to interoperate with a C library that expects C complex values, you won't have any trouble.
C11:
Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.
C++11:
If
z
is an lvalue expression of type cvstd::complex<T>
then:— the expression
reinterpret_cast<cv T(&)[2]>(z)
shall be well-formed,—
reinterpret_cast<cv T(&)[2]>(z)[0]
shall designate the real part ofz
, and—
reinterpret_cast<cv T(&)[2]>(z)[1]
shall designate the imaginary part ofz
.
Use the C keyword for complex: _Complex. C++ uses complex as a (template) class. I'm not sure where creal is or I would uncomment that.
#include <complex.h>
#include <cstdio>
int main(int argc, char * argv[]) {
double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART
//printf("%lf\n", creal(a));
return 0;
}
This works in gcc (I compiled with g++). I got a warning about deprecated .h headers.
Here is a link to an email trail showing nonstandard compatibility with C++ and C with complex numbers. C++11 requires layout compatibility of C++ complexes with C _Complexes.
I'm currently investigating creal, etc. in C++. I'm not finding anything in the standard. Since there seems to be some effort to provide some source compatibility between C++ and C then creal, cpow, etc. might make a nice addition to TR2 the library proposals.
Compatibility of C and C++
Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, designated initializers, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[4] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, are present in the new C++ standard, C++11. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.