Incompatible with g++ on boolean expression as template argument

Incompatible with g++ on boolean expression as template argument

The following code can be compiled by g++ but not icpc.

Any idea to solve this issue without modifying the code?

my g++ and icpc version info:

$ g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)

$ icpc -v
icpc version 13.0.1 (gcc version 4.4.7 compatibility)

#include <iostream>

template<bool B> class CompileTimeAssert { };
template<> class CompileTimeAssert<true> {
public:
static inline void Check() { }
};

#define COMPILE_TIME_ASSERT(b) CompileTimeAssert<(b)>::Check()

int main()
{
COMPILE_TIME_ASSERT(true && "err msg");
std::cout<<(true && "err msg")<<std::endl;
return 0;
}

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

For icpc, here is the error message.

$ icpc a.cpp -o a
a.cpp(13): error: non-integral operation not allowed in nontype template argument
COMPILE_TIME_ASSERT(true && "err msg");
^

a.cpp(13): error: class "CompileTimeAssert<<error-constant>>" has no member "Check"
COMPILE_TIME_ASSERT(true && "err msg");
^

compilation aborted for a.cpp (code 2)

I just verified and older versions of Intel C++ compiler couldn't compile that test case. The error is the same:

...
Test28.cpp(19): error: non-integral operation not allowed in nontype template argument
COMPILE_TIME_ASSERT( true && "err msg" );
^

Test28.cpp(19): error: class "CompileTimeAssert<>" has no member "Check"
COMPILE_TIME_ASSERT( true && "err msg" );
^
...

However, Microsoft C++ compiler also couldn't compile it. Here is its compilation output:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

...
Test28.cpp
C:\VS.2005\VC\INCLUDE\xlocale(326) : warning C4530: C++ exception handler used, but
unwind semantics are not enabled. Specify /EHsc
C:\VS.2005\VC\INCLUDE\xlocale(341) : warning C4530: C++ exception handler used, but
unwind semantics are not enabled. Specify /EHsc
C:\VS.2005\VC\INCLUDE\xlocale(358) : warning C4530: C++ exception handler used, but
unwind semantics are not enabled. Specify /EHsc
C:\VS.2005\VC\INCLUDE\istream(1075) : warning C4530: C++ exception handler used, but
unwind semantics are not enabled. Specify /EHsc
Test28.cpp(19) : error C2975: 'B' : invalid template argument for 'CompileTimeAssert', expected compile-time constant expression
Test28.cpp(5) : see declaration of 'B'
Test28.cpp(19) : error C2039: 'Check' : is not a member of 'CompileTimeAssert[B]'
with
[
B=false
]
Test28.cpp(19) : error C3861: 'Check': identifier not found
...

Simply for your reference.

>>...error C2975: 'B' : invalid template argument for 'CompileTimeAssert', expected compile-time constant expression

This is what MSDN says about C2975 compilation error:

...
The template argument does not match the template declaration; a constant expression should appear within the angle brackets. Variables are not allowed as template actual arguments. Check the template definition to find the correct types.
...

My question regarding your test case: Is that a feature introduced in C++11 standard or not?

i don't think it is. the code can be compiled by this cmd line

g++ -std=c++98 a.cpp -o a

You will note, in accordance with Sergey's hint, that icpc has no trouble with your example when you set -std=c++11 and have a g++ on path which supports that option.  Apparently, this is another c++11 feature which was supported by g++ outside of the option but is not inherited by icpc in that mode.

>>>>...My question regarding your test case: Is that a feature introduced in C++11 standard or not?
>>
>>i don't think it is. the code can be compiled by this cmd line
>>
>>g++ -std=c++98 a.cpp -o a

It looks like some kind of feature of GCC-like C++ compilers. A very old version of g++ from MinGW v3.4.2 for Windows successfully compiled the test case.

I'm still Not sure that this is a bug with Intel and Microsoft C++ compilers.

Here is another verification with a version 12 of Intel C++ compiler:

..\Tests>icl.exe /Qstd=c++0x Test28.cpp
Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.1.7.371 Build 20120928
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.

Test28.cpp
Test28.cpp(19): error: non-integral operation not allowed in nontype template argument
COMPILE_TIME_ASSERT( ( true && "err msg" ) );
^

Test28.cpp(19): error: class "CompileTimeAssert<>" has no member "Check"
COMPILE_TIME_ASSERT( ( true && "err msg" ) );
^

compilation aborted for Test28.cpp (code 2)

icpc 13.0.1 with -std=c++0x option also fails.

$ icpc -std=c++11 a.cpp
a.cpp(13): error: non-integral operation not allowed in nontype template argument
COMPILE_TIME_ASSERT(true && "err msg");
^

a.cpp(13): error: class "CompileTimeAssert<<error-constant>>" has no member "Check"
COMPILE_TIME_ASSERT(true && "err msg");
^

compilation aborted for a.cpp (code 2)

Here is another verification with a Borland C++ compiler ( it is very robust and reliable even if it is very old ):

...
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Test28.cpp:
Error E2396 Test28.cpp 20: Template argument must be a constant expression in function main()
Error E2379 Test28.cpp 20: Statement missing ; in function main()
*** 2 errors in Compile ***
...

I think this is Non standard application of the C/C++ statement / construction.

Once again, I'm Not sure that this is the bug with Intel, Microsoft and Borland C++ compilers. I would simply apply a workaround instead of waiting for a response from Intel C++ compiler team software engineers. Even if they admit '...We're going to fix it...' it could take some time and do not expect a fix by the end of this week.

I would not expect a new backward compatibility fix when icpc working of -std=c++11 has been supported on top of g++ 4.7 and newer for some time.  You're certainly entitled to file a question using your premier.intel.com support account if you have reasons for wanting this compatibility or hope to get an explanation of the reasoning for requiring a more up to date g++.  I would guess that it didn't make sense to attempt to support minor bits of c++11 with interfaces which no longer exist in current g++.

I agree that it looks like a gap in claimed compatibility with RHEL.  As noted in another thread, claimed compatibility with older Fedora versions which aren't updated to g++ 4.7 has been dropped.

Leave a Comment

Please sign in to add a comment. Not a member? Join today