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

Multiple constexpr bugs

asd__asdqwe
Beginner
704 Views

Hello,

The following program doesn't compile with icpc version 15.0.1 but compiles fine with clang++ 3.5 and g++ 4.9.2:

#include <iostream>
#include <type_traits>

template<class K>
class Bar {
    public:
        typedef K type;
};

template<class K>
class Foo {
    public:
        static constexpr const char* const foobar = std::is_same<K, typename Bar<K>::type>::value ? "yo" : "lo";
};

Searching for a workaround on the web, it looks like the following bug is still present with icpc version 15.0.1: http://stackoverflow.com/questions/22540153/intel-icpc-constexpr (compiles fine with clang++ 3.5 and g++ 4.9.2).

Could you please confirm that you can reproduce both bugs ? If so, could you figure out a work around please ?

Thank you for looking.

0 Kudos
12 Replies
Shenghong_G_Intel
704 Views

Hi,

I can confirm these 2 test case will fail with current latest 15.0 update 1 compiler. I've submitted several similar constexpr issues to developer, I'll confirm whether there is a workaround (maybe not as the case is minimal...except not using this new feature...).

Below one looks very similar to your case ("? :" should be very similar to the return value of a function):

https://software.intel.com/en-us/forums/topic/536871

Below one looks very similar to the stackoverflow case:

https://software.intel.com/en-us/forums/topic/536832

According to developer, these 2 issues are same root cause, I'll check with developer whether your 2 test case are same. 

Thanks,

Shenghong

0 Kudos
Shenghong_G_Intel
704 Views

Hi,

I've discussed with developer and there are no simple workaround for these issues, and they may have different root cause from compiler viewpoint. I've submitted them (the one here and the one in stackoverflow) into our problem racking system.

I'll update you if we have any updates on the fix.

Thanks,

Shenghong

0 Kudos
Bernard
Valued Contributor I
704 Views

I suppose that compiler somehow failed to evaluate at compile time equivalence of those two types hence the failed compilation.

0 Kudos
asd__asdqwe
Beginner
704 Views

This still doesn't compile properly with icpc 15.0.2.132.

0 Kudos
Walter_D_
Beginner
704 Views

I have a similar problem. The following code fails

constexpr unsigned log2(unsigned n)
{ return n<2? 0:1+log2(n>>1); }

template<unsigned K>
class C
{
   static constexpr auto A=K;
   static constexpr auto B=log2(B);  // error here; no error for B=log2(K);
};

with the error message "function call must have a constant value in a constant expression".

 

0 Kudos
Bernard
Valued Contributor I
704 Views

I think that in your case Log2(type B) auto deduction of return type could have some dependency on the argument.

0 Kudos
Shenghong_G_Intel
704 Views

@qweasd q.

Some updates for you:

1. Yes, this issue is not fixed in U2 release, I'll update you if I see a fix.

2. The issue in stackoverflow (http://stackoverflow.com/questions/22540153/intel-icpc-constexpr), is fixed in mainline. You may see the fix in U3 release if no exception.

@Walter D.,

For your test case, it looks like to have a minor error in it (it should be "log2(A)" instead of "log2(B)" as B is not declared...). With the updated test case, I can reproduce the issue and I'll submit it to developer team to fix. I do not think it is same issue as this thread. You may submit a new thread (and let me know) or keep en eye on this thread, I'll update you on the progress accordingly. 

# g++ temp.cpp -std=c++11 -c
# icc temp.cpp  -std=c++11 -c
temp.cpp(8): error: function call must have a constant value in a constant expression
     static constexpr auto B=log2(A);  // error here; no error for B=log2(K);
                             ^

compilation aborted for temp.cpp (code 2)
# icc -V
Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.2.164 Build 20150121
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

# cat temp.cpp
constexpr unsigned log2(unsigned n)
{ return n<2? 0:1+log2(n>>1); }

template<unsigned K>
class C
{
   static constexpr auto A=K;
   static constexpr auto B=log2(A);  // error here; no error for B=log2(K);
};
#

Thanks,

Shenghong

0 Kudos
Shenghong_G_Intel
704 Views

@Walter D.,

A easy workaround for your test case is to cast the argument as below:

static constexpr auto B=log2((unsigned)A); // workaround -- cast argument type to match call 

Thanks,

Shenghong

0 Kudos
asd__asdqwe
Beginner
704 Views

Hello,

Why hasn't this been fixed in icpc 16 ?

0 Kudos
asd__asdqwe
Beginner
704 Views

Please, I still can't compile this example, why ?

#include <iostream>
#include <type_traits>

template<class K>
class Bar {
    public:
        typedef K type;
};

template<class K>
class Foo {
    public:
        static constexpr const char* const foobar = std::is_same<K, typename Bar<K>::type>::value ? "yo" : "lo";
};

 

0 Kudos
Shenghong_G_Intel
704 Views

Hi qweasd.

I've checked the status of the issue and it is not fixed in v16.0 yet. I'll push developer to have a quicker fix. Sorry for that.

By the way, we have 3 issues mentioned in this thread, Walter's issue is also not fixed but it is fixed in mainline (hope to see it in next update). Stackoverflow's issue is fixed already long ago (I've double confirmed again with v16.0 initial release).

Thanks,

Shenghong

0 Kudos
Judith_W_Intel
Employee
704 Views

 

This was fixed in mid November (it was tracked in DPD200365974) and should appear in 16.0 Update 2.

Sorry for the inconvenience.

This is a description of the fix:


Array to pointer decay in dependent constant expressions

The front end previously erroneously treated an array to pointer decay as
making a dependent expression non-constant.  Such expressions are now
accepted as constant during prototype instantiation.  For example, with
--c++11:

  template<typename T1, typename T2> struct A {
    static constexpr bool v = true;
  };
  template<typename T> struct B {
    typedef T t;
  };
  template<typename T> struct C {
    static constexpr const char* const x =
      A<T, typename B<T>::t>::v ? "t" : "f";  // Previously not constant
                                              // because of array to ptr decay
  };

0 Kudos
Reply