l’identifiant “creal” n’est pas défini – visible sur Mac mais pas sous Linux

Question

Le code suivant est-il incorrect ou existe-t-il un problème avec les en-têtes sur Mac? L’erreur n’apparaît pas sous Linux, ce qui m’amène à conclure qu’il ne s’agit pas d’un code incorrect, bien qu’une compilation réussie sous Linux ne constitue pas un test particulièrement rigoureux pour la conformité ISO.

Code source (MCVE)

#include  #include  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

Information système

 $ 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 

Compilateur 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) 

Compilateur 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

Information système

 $ 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 

Compilateur 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  

Compilateur Intel

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

Compilateur 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  

Enquête

J’ai lu tous les en-têtes complex.h , complex.h , complex et complex sur mon Mac, mais je ne vois pas de raison évidente à ce problème.

Ceci est juste la lecture par Clang de la norme C ++ – voir cette réponse – qui me semble être la bonne. En principe, vous n’êtes pas censé utiliser le type complexe C99 et les fonctions associées en C ++ et std::complex utiliser std::complex place. Les deux types complexes doivent être compatibles avec la présentation et vous devez pouvoir transmettre des données complexes entre les codes C et C ++.

g++ g++ comprend à la fois (en mode C ++ 11) et le C et, par conséquent, le code est compilé avec GCC (de Homebrew dans mon cas). Je n’ai pas le compilateur Intel pour OS X, mais vous pouvez vérifier ce qu’il fait avec icpc -E ttc-creal.cpp | grep complex icpc -E ttc-creal.cpp | grep complex et observez la séquence des extensions de fichiers include.

Bruit:

 $ 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 

Vous pouvez forcer Clang à inclure /usr/include/complex.h par exemple:

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

et votre MCVE comstackra, mais cela est probablement une très mauvaise idée ™.

Soit dit en passant, le même comportement est observé sous FreeBSD 10.2-RELEASE avec Clang 3.4.1 (erreur) et GCC 4.8.5 (succès).

Tout le mérite revient à Potatoswatter – l’auteur de la réponse mentionnée en haut.