I am compiling on OSX using Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Specifically, I am trying to compile a monolithic source
<complex.h>
is a C header and it is not compatible with C++.
C++ defines C library compatibility through headers named in the pattern <c***>
. So, the C++ counterpart to <complex.h>
is named <ccomplex>
. Here's what the C++ standard has to say about that:
Header
<ccomplex>
The header behaves as if it simply includes the header
<complex>
.
If you attempt to use the C complex number library, you just get the C++ one instead.
Bottom line: you simply cannot run C complex math through a C++ compiler. At best, you can use the preprocessor to generate equivalent programs depending on __cplusplus
.
For example,
#if __cplusplus
# include <complex>
typedef std::complex< double > cdouble;
#else
# include <complex.h>
typedef double complex cdouble;
#endif
Note, std::complex< double >
and double complex
are layout-compatible per C++14 [complex.numbers] §26.4/4 and C11 §6.2.5/13. The intent seems to be that you can use cdouble
for cross-language function prototypes, although strictly speaking it depends on the ABI.
Incidentally, the C++ standard does define what happens when you #include <complex.h>
, but it doesn't make any sense:
Every C header, each of which has a name of the form
name.h
, behaves as if each name placed in the standard library namespace by the correspondingcname
header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespacestd
and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
So, #include <complex.h>
should give you a global ::complex<T>
. This is a defect in the standard.