Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

ICC 16.0.3 / GCC 6.1: Problems with cmath include

Bastian_B_
New Contributor I
922 Views

Hello,

When trying to compile this code:

#include <cmath>
#include <math.h>
#include <iostream>

int main(int argc, char** argv) {
  double x = sqrt(-1);
  if (std::isnan(x))
    std::cout << "NAN!" << std::endl;
  return 0;
}

with ICC 16.0.3 and GCC 6.1 backend on Linux the following error message is generated:

isnan.cc(7): error: expected an identifier 
   if (std::isnan(x))
            ^
compilation aborted for isnan.cc (code 2)

This compiles fine with GCC 4.9, GCC 5.3, GCC 6.1, ICC 16.0.3 (GCC 4.9 backend), ICC 16.0.3 (GCC 5.3 backend), but NOT with ICC 16.0.3 (GCC 6.1 backend). The problem appears to be arise because of a change in the GCC 6 cmath header.

This is the relevant hunk of the diff between the 5.3 cmath and the 6.1 cmath:

@@ -41,7 +41,9 @@
 #include <bits/c++config.h>
 #include <bits/cpp_type_traits.h>
 #include <ext/type_traits.h>
-#include <math.h>
+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
+#include_next <math.h>
+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
 
 #ifndef _GLIBCXX_CMATH
 #define _GLIBCXX_CMATH 1
The Intel math.h is included in the GCC 5.3.0 case, but not in the GCC 6.1. Therefore, when in line 2 of my test program math.h is included, the following happens: With GCC 5.3.0 the include is ignored because it was already processed and the include guard is setd, and in the GCC 6.1 case the include is not ignored, leading to the definition of the isnan macro, which causes the compiler error.

To phrase the issue differently: With GCC 6.1 the Intel provided math.h is not included at all when one does:

#include <cmath>

This is also illustrated by using the -H option of icpc when compiling the program posted in the beginning.

With GCC 5.3.0:

. /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/cmath 
.. /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/x86_64-unknown-linux-gnu/bits/c++config.h
... /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/x86_64-unknown-linux-gnu/bits/os_defines.h
.... /usr/include/features.h
..... /usr/include/stdc-predef.h
..... /usr/include/sys/cdefs.h
...... /usr/include/bits/wordsize.h
..... /usr/include/gnu/stubs.h
...... /usr/include/gnu/stubs-64.h
... /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/x86_64-unknown-linux-gnu/bits/cpu_defines.h
.. /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/bits/cpp_type_traits.h
.. /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/include/c++/ext/type_traits.h
.. /opt/intel/compilers_and_libraries_2016.2.181/linux/compiler/include/math.h
... /usr/include/math.h
.... /usr/include/bits/math-vector.h
..... /usr/include/bits/libm-simd-decl-stubs.h
.... /usr/include/bits/huge_val.h
.... /usr/include/bits/huge_valf.h
.... /usr/include/bits/huge_vall.h
.... /usr/include/bits/inf.h
.... /usr/include/bits/nan.h
.... /usr/include/bits/mathdef.h
.... /usr/include/bits/mathcalls.h
.... /usr/include/bits/mathcalls.h
.... /usr/include/bits/mathcalls.h
.... /usr/include/bits/mathinline.h
. /opt/intel/compilers_and_libraries_2016.2.181/linux/compiler/include/math.h

 With GCC 6.1.1:

. /usr/include/c++/6.1.1/cmath 
.. /usr/include/c++/6.1.1/x86_64-pc-linux-gnu/bits/c++config.h
... /usr/include/c++/6.1.1/x86_64-pc-linux-gnu/bits/os_defines.h
.... /usr/include/features.h
..... /usr/include/stdc-predef.h
..... /usr/include/sys/cdefs.h
...... /usr/include/bits/wordsize.h
..... /usr/include/gnu/stubs.h
...... /usr/include/gnu/stubs-64.h
... /usr/include/c++/6.1.1/x86_64-pc-linux-gnu/bits/cpu_defines.h
.. /usr/include/c++/6.1.1/bits/cpp_type_traits.h
.. /usr/include/c++/6.1.1/ext/type_traits.h
.. /usr/include/math.h
... /usr/include/bits/math-vector.h
.... /usr/include/bits/libm-simd-decl-stubs.h
... /usr/include/bits/huge_val.h
... /usr/include/bits/huge_valf.h
... /usr/include/bits/huge_vall.h
... /usr/include/bits/inf.h
... /usr/include/bits/nan.h
... /usr/include/bits/mathdef.h
... /usr/include/bits/mathcalls.h
... /usr/include/bits/mathcalls.h
... /usr/include/bits/mathcalls.h
... /usr/include/bits/mathinline.h
. /opt/intel/compilers_and_libraries_2016.2.181/linux/compiler/include/math.h
.. /usr/include/c++/6.1.1/math.h
... /usr/include/c++/6.1.1/cmath

Any advice how to workaround this issue? Will the next ICC release be compatible with the GCC 6 headers?

Cheers

Bastian 

0 Kudos
2 Replies
Anoop_M_Intel
Employee
922 Views

Hi Bastian,

Intel C++ Compiler 16.0 Update 3 supports GCC 4.1 to 5.1 as documented at https://software.intel.com/en-us/articles/intel-c-compiler-160-for-linux-release-notes-for-intel-parallel-studio-xe-2016. Will surely keep you posted when we start supporting GCC 6. Considering there is a header change introduced in GCC 6, I will bring this to the attention of our compiler engineers. 

Thanks and Regards
Anoop

0 Kudos
Anoop_M_Intel
Employee
922 Views

Hi Bastian,

I have filed an internal tracker to track this change in GCC 6 which breaks the out-of-the-box compatibility. Will keep you posted when we officially are compatible with GCC 6.

Thanks and Regards
Anoop

0 Kudos
Reply