Community
cancel
Showing results for 
Search instead for 
Did you mean: 
asd__asdqwe
Beginner
89 Views

Multiple constexpr bugs

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

89 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

Bernard
Black Belt
89 Views

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

asd__asdqwe
Beginner
89 Views

This still doesn't compile properly with icpc 15.0.2.132.

Walter_D_
Beginner
89 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".

 

Bernard
Black Belt
89 Views

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

89 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

89 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

asd__asdqwe
Beginner
89 Views

Hello,

Why hasn't this been fixed in icpc 16 ?

asd__asdqwe
Beginner
89 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";
};

 

89 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

Judith_W_Intel
Employee
89 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
  };

Reply