идентификатор & quot; creal & quot; не определено — видно на Mac, но не на Linux

Следующий код неправильный или есть проблема с заголовками на Mac? Ошибка не появляется в Linux, что позволяет мне сделать вывод, что это не неправильный код, хотя успешная компиляция в Linux не является особенно строгим тестом на соответствие ISO.

#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]]));
}
}
}

Системная информация

$ 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

Компилятор Intel

$ 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.

Системная информация

$ 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>

Компилятор Intel

$ 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>

Я прочитал все соответствующие complex.h, ccomplex а также complex заголовки на моем Mac, но не вижу очевидной причины этой проблемы.

2

Решение

Это всего лишь чтение Clang стандарта C ++ — см. этот ответ — что мне кажется правильным. По сути, вы не должны использовать сложный тип C99 и связанные функции в C ++ и должны использовать std::complex<T> вместо. Оба сложных типа должны быть совместимы с макетом, и вы должны иметь возможность передавать сложные данные между кодом C и C ++.

g++«s complex.h включает в себя как <ccomplex> (в режиме C ++ 11) и C <complex.h> и, следовательно, код компилируется с GCC (от Homebrew в моем случае). У меня нет компилятора Intel для OS X, но вы можете проверить, что он делает с icpc -E ttc-creal.cpp | grep complex и наблюдать за последовательностью расширений включаемых файлов.

Clang:

$ 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

GCC:

$ 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 например:

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

и ваш MCVE будет компилироваться, но это, вероятно, очень плохая идея (тм).

Кстати, такое же поведение наблюдается на FreeBSD 10.2-RELEASE с Clang 3.4.1 (ошибка) и GCC 4.8.5 (успех).

Вся заслуга принадлежит Potatoswatter — автору ответа, указанному наверху.

1

Другие решения

Других решений пока нет …