问题描述
以下代码是否错误,或者Mac上的标头存在问题?该错误未在Linux上出现,这使我得出结论,它不是错误的代码,尽管在Linux上成功编译并不是对ISO遵从性进行特别严格的测试.
Is the following code wrong or is there an issue with the headers on Mac? The error does not appear on Linux, which leads me to conclude it is not incorrect code, although successful compilation on Linux is not a particularly rigorous test for ISO compliance.
#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.h
,ccomplex
和complex
标头,但看不到出现此问题的明显原因.
Investigation
I have read through all of the relevant complex.h
, ccomplex
and complex
headers on my Mac, but cannot see an obvious reason for this issue.
推荐答案
这只是Clang对C ++标准的解读-参见那个答案-在我看来,这是正确的.基本上,您不应该在C ++中使用C99复杂类型和关联函数,而应该使用std::complex<T>
.两种复杂类型都应与布局兼容,并且您应该能够在C和C ++代码之间传递复杂数据.
This is just Clang's read of the C++ standard - see that answer - which to me appears to be the correct one. Basically, you are not supposed to use the C99 complex type and the associated functions in C++ and should use std::complex<T>
instead. Both complex types should be layout-compatible and you should be able to pass complex data between C and C++ code.
g++
的complex.h
包括<ccomplex>
(在C ++ 11模式下)和C <complex.h>
,因此代码使用GCC(在我的情况下为Homebrew)进行编译.我没有用于OS X的Intel编译器,但是您可以检查icpc -E ttc-creal.cpp | grep complex
的功能,并观察包含文件扩展的顺序.
g++
's complex.h
includes both <ccomplex>
(in C++11 mode) and the C <complex.h>
and therefore the code compiles with GCC (from Homebrew in my case). I don't have the Intel compiler for OS X, but you could check what it does with icpc -E ttc-creal.cpp | grep complex
and observe the sequence of include file expansions.
C语:
$ 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包含<path to SDK>/usr/include/complex.h
:
You can force Clang to include <path to SDK>/usr/include/complex.h
by e.g.:
#include "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/complex.h"
您的MCVE将会编译,但是这样做可能是一个非常糟糕的主意(tm).
and your MCVE will compile, but doing so is probably a very Bad Idea (tm).
顺便说一下,在带有Clang 3.4.1(错误)和GCC 4.8.5(成功)的FreeBSD 10.2-RELEASE上观察到了相同的行为.
By the way, the same behaviour is observed on FreeBSD 10.2-RELEASE with Clang 3.4.1 (error) and GCC 4.8.5 (success).
所有功劳归功于Potatoswatter-顶部引用答案的作者.
这篇关于标识符"creal"未定义-在Mac上可见,但在Linux上不可见的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!