标识符“creal”未定义 - 在 Mac 上可见但在 Linux 上不可见

Posted

技术标签:

【中文标题】标识符“creal”未定义 - 在 Mac 上可见但在 Linux 上不可见【英文标题】:identifier "creal" is undefined - seen on Mac but not on Linux 【发布时间】:2016-04-20 14:48:51 【问题描述】:

问题

以下代码是错误的还是 Mac 上的标头有问题?该错误在 Linux 上没有出现,这使我得出结论,这不是错误代码,尽管在 Linux 上成功编译并不是对 ISO 合规性的特别严格的测试。

源代码 (MCVE)

#include <stdio.h>
#include <complex.h>

void foo(const double *A, int *size)
   for(int i=0;i < size[0]; ++i)
      for(int j=0;j < size[1]; ++j)
         printf("(%.2e,%.2e) ", creal(A[i + j * size[0]]), cimag(A[i + j * size[0]]));
      
   

Mac

系统信息

$ uname -a
Darwin redacted 15.4.0 Darwin Kernel Version 15.4.0: Fri Feb 26 22:08:05 PST 2016; root:xnu-3248.40.184~3/RELEASE_X86_64 x86_64

英特尔编译器

$ icpc -v
icpc version 16.0.2 (gcc version 4.9.0 compatibility)
$ icpc -c ttc-creal.cpp 
ttc-creal.cpp(7): error: identifier "creal" is undefined
           printf("(%.2e,%.2e) ", creal(A[i + j * size[0]]), cimag(A[i + j * size[0]]));
                                  ^

ttc-creal.cpp(7): error: identifier "cimag" is undefined
           printf("(%.2e,%.2e) ", creal(A[i + j * size[0]]), cimag(A[i + j * size[0]]));
                                                             ^

compilation aborted for ttc-creal.cpp (code 2)

LLVM 编译器

$ clang++ -v
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ clang++ -c ttc-creal.cpp 
ttc-creal.cpp:7:33: error: use of undeclared identifier 'creal'
         printf("(%.2e,%.2e) ", creal(A[i + j * size[0]]), cimag(A[i + j * size[0]]));
                                ^
ttc-creal.cpp:7:60: error: use of undeclared identifier 'cimag'
         printf("(%.2e,%.2e) ", creal(A[i + j * size[0]]), cimag(A[i + j * size[0]]));
                                                           ^
2 errors generated.

Linux

系统信息

$ uname -a
Linux redacted 2.6.32-573.18.1.el6.centos.plus.x86_64 #1 SMP Wed Feb 10 18:09:24 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

GNU 编译器

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/gcc/5.3.0/libexec/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /home/redacted/Work/GCC/gcc-5.3.0/configure --prefix=/opt/gcc/5.3.0 --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --enable-languages=c,c++,fortran --with-tune=native --enable-bootstrap --enable-lto --with-mpfr --with-isl --with-gmp --with-mpc --with-cloog --enable-gold --enable-ld --disable-multilib
Thread model: posix
gcc version 5.3.0 (GCC) 
$ g++ -c ttc-creal.cpp
<no error>

英特尔编译器

$ icpc -v
icpc version 17.0.0 Beta (gcc version 5.3.0 compatibility)
$ icpc -c ttc-creal.cpp
<no error>

LLVM 编译器

$ clang++ -v
clang version 3.4.2 (tags/RELEASE_34/dot2-final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.4
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.4.4
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.4.7
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-redhat-linux/4.4.7
$ clang++ -c ttc-creal.cpp 
<no error>

调查

我已经阅读了我 Mac 上所有相关的 complex.hccomplexcomplex 标头,但看不出这个问题的明显原因。

【问题讨论】:

您的 MCVE 可能会更小。在 2 个#includes 之后,您只需要一个带有 1 行的 main():printf("%lf", creal(3.5));。除此之外,我尝试了一些在线编译器。根据melpon.org/wandbox,它适用于 gcc 4.8.1,但没有 Clang 版本编译它。甚至 MSVC 也会出现错误(在 webcompiler.cloudapp.net 和 rextester.com/l/cpp_online_compiler_visual 尝试过)。但我认为问题出在库中,而不是编译器本身。不知道这有多大帮助,抱歉。 【参考方案1】:

这只是 Clang 对 C++ 标准的解读 - 请参阅 that answer - 在我看来,这似乎是正确的。基本上,您不应该在 C++ 中使用 C99 复杂类型和相关函数,而应该使用 std::complex&lt;T&gt;。两种复杂类型都应该是布局兼容的,并且您应该能够在 C 和 C++ 代码之间传递复杂数据。

g++complex.h 包括 &lt;ccomplex&gt;(在 C++11 模式下)和 C &lt;complex.h&gt;,因此代码使用 GCC 编译(在我的例子中来自 Homebrew)。我没有适用于 OS X 的 Intel 编译器,但您可以检查它对 icpc -E ttc-creal.cpp | grep complex 的作用,并观察包含文件扩展的顺序。

叮当声:

$ clang++ -E ttc-creal.cpp | grep "^# 1 " | grep complex
# 1 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex.h" 1 3
# 1 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ccomplex" 1 3
# 1 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/complex" 1 3

海合会:

$ g++-5 -E ttc-creal.cpp | grep "^# 1 " | grep complex
# 1 "/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/complex.h" 1 3
# 1 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/complex.h" 1 3 4

$ g++-5 -std=c++11 -E ttc-creal.cpp | grep "^# 1 " | grep complex
# 1 "/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/complex.h" 1 3
# 1 "/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/ccomplex" 1 3
# 1 "/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/complex" 1 3
# 1 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/complex.h" 1 3 4

您可以强制 Clang 包含 &lt;path to SDK&gt;/usr/include/complex.h,例如:

#include "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/complex.h"

您的 MCVE 将编译,但这样做可能是一个非常糟糕的主意 (tm)。

顺便说一句,在使用 Clang 3.4.1(错误)和 GCC 4.8.5(成功)的 FreeBSD 10.2-RELEASE 上观察到了相同的行为。

所有功劳归于 Potatoswatter - 顶部引用的答案的作者。

【讨论】:

谢谢。将此添加到我讨厌 C++ 的原因列表中,但不幸的是,我没有编写有问题的代码,因此我无法控制更改它。

以上是关于标识符“creal”未定义 - 在 Mac 上可见但在 Linux 上不可见的主要内容,如果未能解决你的问题,请参考以下文章

硬件(MAC)地址的概念及作用

matlab函数和变量无法识别怎么办?

未定义标识符/未声明

mac上的架构x86_64错误的未定义符号

“使用未解析的标识符字符串“自定义键盘

架构 x86_64 的未定义符号:“hex(QTextStream&)”,引用自:(在 Mac 上安装 PyQwt-5.2.0)