Warning: ISO C++ forbids converting a string constant to ‘char*’ for a static `constexpr char*` data member

16,527

Solution 1

constexpr does imply const, but in this case it applies const to the "wrong thing".

constexpr char*

is basically the same as

char * const

which is a constant pointer to a non-const char. This won't work because string literals have the type const char[N] so it would cast away the constness of the array elements.

constexpr const char*

on the other hand, is basically the same as

char const * const

which is a constant pointer to a constant char, which is what you want as it preserves the constness of the elements.

Solution 2

There is a usual difference between a constant pointer and a pointer to constant. By making your constexpr char* you made a pointer itself a constexpr (and, of course, const), but it still attempts to point at non-const character - and this is wrong, as string literals are const. Solution:

constexpr const char* ch = "StackOverflow!";

Which declares a constexpr pointer to const.

Share:
16,527
tmaric
Author by

tmaric

Updated on June 10, 2022

Comments

  • tmaric
    tmaric almost 2 years

    Why does this code return a warning

    warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

    if

    A constexpr specifier used in an object declaration or non-static member function (until C++14) implies const. A constexpr specifier used in a function or static member variable (since C++17) declaration implies inline.

    (cppreference.com)

    #include <cassert>    
    #include <string>    
    #include <iostream>    
    
    struct A     
    {    
        // warning: ISO C++ forbids converting a string constant to ‘char*’    
        static constexpr char* name_ = "A";                           
        static constexpr char* name() { return name_; };             
    };                                             
    
    int main()    
    {};    
    

    If I add a const after constexpr, the warning is gone:

    #include <cassert>    
    #include <string>    
    #include <iostream>   
    
    
    
    struct A     
    {    
        static constexpr const char* name_ = "A";    
        static constexpr const char* name() { return name_; };    
    };                                             
    
    int main()    
    {};  
    

    With g++ --version = g++ (GCC) 8.2.1 20181127,

    compilation g++ -O3 -std=c++2a -Wall main.cpp -o main.

    Does the constexpr not imply const on static data members?