I study constexpr. I can not understand why the compiler does not consider one of the expressions as constant, because it fits the requirements.

Code:

#include <iostream> #include <cstdlib> #include <array> constexpr int f( int x ) { if ( x < 0 ) x = 0; return ++x; } int main() { typedef double T; typedef std::array<T, 3> C; constexpr C c = {1, 2, 3}; constexpr C::const_reference ref = c.at( 0 ); // error: is not a constexpr static_assert( ref == 1, "ref != 1" ); constexpr int y = -3; //y = f( y ); static_assert( f( y ) == 1, "f( y ) != 1" ); return 0; } 

You can compile this link.

In the implementation of stl, with which I work for the array, the at function is declared as constexpr and the array has no constructors at all, the destructor is also not declared, which means the class has a destructor by default, the array itself is initiated, so I don’t know why it does not work.

Interested compilers gcc 5.4.0 and gcc 6.4.0. clang doesn't compile this either.

    1 answer 1

    The concept of "constexpr-link" refers to the properties of the link itself, and not the referenced expression. Constexpr-link assumes that such a link will be tied to an object whose memory location is known at the compilation stage . The situation is almost completely similar to that of constexpr-pointers.

    Your local object does not satisfy this requirement.

    Declare c as

     static constexpr C c = {1, 2, 3}; 

    and you will be able to link links to it and its sub- constexpr .


    (Illustrating with additional examples ...) This code is correct, despite the fact that the link is bound to a regular non-constant variable

     int main() { static int x = 42; constexpr const int &rx = x; } 

    But such a code is not correct, no matter how much const and constexpr we would put on the variable

     int main() { constexpr int y = 42; constexpr const int &ry = y; } 
    • The constexpr object is known at compile time. wandbox.org/permlink/0bJWs6vfLT6ibp2Z - OlegUP
    • one
      Is it like this? The value of the constexpr object can be known at compile time. The position in memory of a constexpr object is not necessarily known at compile time. (Namely: the position in memory is known only for static objects). Constexpr-links require precisely the fame of the position in memory. The value they do not care. Your example of the link is completely past the cash register, because there are no attempts to advertise a constexpr link in it. - AnT
    • Apparently, the case is really in the links, but that test worked out, tomorrow if I accomplish my goal, and maybe there will be another mistake, ok? Simply, I repeat, I tried to re-create the code from memory, and maybe I forgot something. - OlegUP
    • In general, in the implementation I work with at a non-constant function is called. That's why it did not work. As soon as I commented out the call, everything compiled. - OlegUP
    • @ OlegUP: In the sense of "everything compiled"? What exactly was compiled? - AnT