c ++和< complex.h>与< complex>在单独的文件 [英] c++ and <complex.h> with <complex> in separate files

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

问题描述

注意:



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



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

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

$ < 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 ++标准对此的说明:


标题< ccomplex>



标题的行为就像只包含标题< complex>


如果您尝试使用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 时会发生什么,没有任何意义:


每个C头,每个头都有一个名为名称的名称。 h ,如同通过相应的 cname 头放置在标准库命名空间中的每个名称放置在全局命名空间范围。这些名称是否首先在命名空间 std 的命名空间范围(3.3.6)内声明或定义,然后通过显式的注入到全局命名空间范围中,使用声明(7.3.3)。


所以, #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:

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 corresponding cname 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 namespace std 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.

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

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆