本文介绍了c ++和< complex.h>与< complex>在单独的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:



我正在使用Apple LLVM版本6.0(clang-600.0.56)(基于LLVM 3.5svn)在OSX上进行编译



具体来说,我试图从LibIIR编译一个整体源,一个​​过滤库,维护

我已经看过这个答案了。关于同时使用

$ < complex.h>

设置:



我有一个文件 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;
#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:

So, #include <complex.h> should give you a global ::complex<T>. This is a defect in the standard.

这篇关于c ++和&lt; complex.h&gt;与&lt; complex&gt;在单独的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 22:19