c++ - How can a variable be both constexpr and not constexpr? -


i have made constexpr string type, call staticstring. got idea this website.

i having weird issues compiler treating variable constexpr on 1 line, , not constexpr on next line.

here code:

constexpr staticstring hello = "hello"; constexpr staticstring hello2 = hello + " "; constexpr staticstring world = "world"; constexpr staticstring both = hello + " world"; constexpr staticstring both2 = hello2 + world; //this works fine (world constexpr?)  //constexpr staticstring both3 = "hello " + world;  //error: "world" not constexpr  int main(void) {     static_assert(hello[4] == 'o' ,"error");     static_assert(hello == "hello", "error");     static_assert(both2 == "hello world", "error"); } 

and here definition of staticstring:

class staticstring{         const char* const str;         const size_t len;         const staticstring* head;     public:         template<size_t n>         constexpr staticstring(const char(&astr)[n])              : str(astr), len(n-1), head(nullptr)  //chop off null terminating char         {             static_assert(n>=1,"string cannot have negative length");         }         template<size_t n>         constexpr staticstring(const char(&astr)[n] ,const staticstring* ss) : head(ss), str(astr),len(n-1) { }         constexpr staticstring(const char* const astr ,const size_t len,const staticstring* ss = nullptr)              : str(astr), len(len), head(ss)         {         }         constexpr char getfromhead(size_t index) const{             return index < head->getsize() ? (*head)[index] : str[index - head->getsize()];         }         constexpr char operator[](size_t index) const{             return head ? getfromhead(index) : str[index];         }         constexpr size_t getsize() const{             return head ? len + head->getsize() : len;         }         constexpr bool equals(const char* const other,size_t len,size_t index = 0) const{              return (other[0] == (*this)[index]) ? (len > 1 ? equals(&other[1],len-1,index+1) : true) : false;         }         template<size_t n>         constexpr bool operator==(const char(&other)[n]) const{             return equals(other,n-1);         }         template<size_t n>         constexpr staticstring operator+(const char(&other)[n]) const{             return staticstring(other,this);         }         constexpr staticstring operator+(staticstring other) const{             return staticstring(other.str,other.len,this);         }  }; template<size_t n> constexpr staticstring operator+(const char(&str)[n],const staticstring& other){     return staticstring(str) + other; } 

so question this: why world treated constexpr on 1 line not next?

note: error get:

'staticstring{((const char*)"world"), 5ull, ((const prototypeind::util::staticstring*)(&<anonymous>))}' not constant expression 

also using gcc

discussion

your world variable constexpr operator+ in expression:

constexpr staticstring both3 = "hello " + world; 

although marked constexpr not. because in return statement:

return staticstring(str) + other; 

due creation of temporary staticstring(str) pointers non-static-storage duration temporaries being created. attributed fact in staticstring objects you're storing addresses of non-static-storage duration temporaries , these kind of pointers not allowed in constant expressions.

justification

according standard §5.20/p5 constant expressions [expr.const] (emphasis mine):

a constant expression either glvalue core constant expression value refers entity permitted result of constant expression (as defined below), or prvalue core constant expression value satisfies following constraints:

(5.1) — if value object of class type, each non-static data member of reference type refers entity permitted result of constant expression,

(5.2) — if value of pointer type, contains address of object static storage duration, address past end of such object (5.7), address of function, or null pointer value, and

(5.3) — if value object of class or array type, each subobject satisfies these constraints value.

an entity permitted result of constant expression if object static storage duration either not temporary object or temporary object value satisfies above constraints, or function.

.


Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -