问题描述
注意:
我正在使用Apple LLVM版本6.0(clang-600.0.56)(基于LLVM 3.5svn)在OSX上进行编译
具体来说,我试图从LibIIR编译一个整体源,一个过滤库,维护 我已经看过这个答案了。关于同时使用
设置:
我有一个文件 iir.h >
#include< complex.h>
#ifdef __cplusplus
externC{
#endif
...
pre>
我有C ++源文件和头文件 libiir ++。cpp 和 iir ++。h 如下:
/ *** libiir ++。cpp *** /
我们需要首先包括iir.h,因为它拉入< complex.h> ;,其中我们需要
//在iir ++。h拉入< complex>
#includeiir.h
//现在删除复杂的预处理器定义到_Complex,这是罚款
//为C头,但不好的C ++ header
#undef complex
#includeiir ++。h
命名空间IIR {
...
-
*** iir ++。h *** /
#include< complex>
命名空间IIR {
...
问题:
clang在编译时给出以下错误:
./ iir.h:570:15:error:expected';'在顶级声明器之后
double complex iir_response_c(const struct iir_coeff_t * coeff,double freq);
^
;
显然,新的< complex> 导入不发生 - 或 #undef complex 再次发生 - 但我不知道如何。
解决方案< complex.h> ;
C ++通过在模式中命名的头文件定义C库兼容性< c ***> 。因此,< complex.h> 的C ++对应名为< ccomplex> 。以下是C ++标准对此的说明:
如果您尝试使用C复数库,您只需要获取C ++。
底线:你根本不能通过C ++编译器运行C复杂数学。至多,您可以使用预处理程序根据 __ cplusplus 生成等效程序。
例如,
#if __cplusplus
#include< complex>
typedef std :: complex< double> cdouble;
#else
#include< complex.h>
typedef double complex cdouble;
#endif
注意, std :: complex< double> 和 double complex 是布局兼容的每个C ++ 14 [complex.numbers]§26.4/ 4和C11§6.2.5 / 13。目的似乎是,您可以使用 cdouble 用于跨语言函数原型,但严格来说它取决于ABI。
顺便说一下,C ++标准定义了当 #include 时会发生什么,没有任何意义:
所以, #include& h> 应该给你一个全局 :: complex< T> 。这是标准中的缺陷。
Notes:
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 from LibIIR, a filter library maintained here by Laurence Withers.
I've already looked at this answer here about using both <complex> and <complex.h> in the same file.
Setup:
I have a file iir.h like so:
#include <complex.h> #ifdef __cplusplus extern "C" { #endif ...I have C++ source and header files libiir++.cpp and iir++.h like so:
/*** libiir++.cpp ***/ // we need to include "iir.h" first, as it pulls in <complex.h>, which we need // to take effect before "iir++.h" pulls in <complex> #include "iir.h" // now remove the preprocessor definition of complex to _Complex, which is fine // for the C header but not good for the C++ header #undef complex #include "iir++.h" namespace IIR { ...-
/*** iir++.h ***/ #include <complex> namespace IIR { ...Problem:
clang gives me the following error when compiling:
./iir.h:570:15: error: expected ';' after top level declarator double complex iir_response_c(const struct iir_coeff_t* coeff, double freq); ^ ;Evidently, the new <complex> import is not happening--or #undef complex is happening again--but I don't see how. Any advice on what might be going wrong, or what to check?
解决方案<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:
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; #endifNote, 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:
So, #include <complex.h> should give you a global ::complex<T>. This is a defect in the standard.
这篇关于c ++和< complex.h>与< complex>在单独的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!