c ++和在单独的文件中包含

笔记:

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

具体来说,我正在尝试从LibIIR编译一个单片源, 这是Laurence Withers 在这里维护的filter库。

我已经在这里看到了关于在同一个文件同时使用答案。


建立:

我有一个像iir.h这样的文件:

 #include  #ifdef __cplusplus extern "C" { #endif ... 

我有C ++源代码和头文件libiir++.cppiir++.h喜欢这样:

 /*** libiir++.cpp ***/ // we need to include "iir.h" first, as it pulls in , which we need // to take effect before "iir++.h" pulls in  #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  namespace IIR { ... 

问题:

clang在编译时给出了以下错误:

 ./iir.h:570:15: error: expected ';' after top level declarator double complex iir_response_c(const struct iir_coeff_t* coeff, double freq); ^ ; 

显然,新的导入没有发生 – 或#undef complex再次发生 – 但我不知道如何。 关于可能出现的问题或检查内容的任何建议?

是一个C头,它与C ++不兼容。

C ++通过模式指定的标头定义C库兼容性。 因此, 的C ++对应名为 。 以下是C ++标准对此的评价:

标题

标题的行为就像它只包含标题

如果您尝试使用C复数库,则只需获取C ++编号。

结论:您无法通过C ++编译器运行C复杂数学运算。 充其量,您可以使用预处理器根据__cplusplus生成等效程序。

例如,

 #if __cplusplus # include  typedef std::complex< double > cdouble; #else # include  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头,每个头都有一个名称为name.h行为,就好像每个由相应的cname头放在标准库命名空间中的名称放在全局命名空间范围内。 未指定是在名称空间std的名称空间作用域(3.3.6)中首先声明或定义这些名称,然后通过显式using-declarations (7.3.3)将这些名称注入到全局名称空间作用域中。

所以, #include 应该给你一个global ::complex 。 这是标准中的缺陷。