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












19















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?










share|improve this question

























  • stackoverflow.com/questions/28845058/…

    – Mat
    14 hours ago











  • stackoverflow.com/questions/14116003/…

    – Brandon Lyons
    14 hours ago
















19















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?










share|improve this question

























  • stackoverflow.com/questions/28845058/…

    – Mat
    14 hours ago











  • stackoverflow.com/questions/14116003/…

    – Brandon Lyons
    14 hours ago














19












19








19


1






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?










share|improve this question
















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?







c++ c++11 static constexpr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 14 hours ago







tmaric

















asked 14 hours ago









tmarictmaric

2,6651949




2,6651949













  • stackoverflow.com/questions/28845058/…

    – Mat
    14 hours ago











  • stackoverflow.com/questions/14116003/…

    – Brandon Lyons
    14 hours ago



















  • stackoverflow.com/questions/28845058/…

    – Mat
    14 hours ago











  • stackoverflow.com/questions/14116003/…

    – Brandon Lyons
    14 hours ago

















stackoverflow.com/questions/28845058/…

– Mat
14 hours ago





stackoverflow.com/questions/28845058/…

– Mat
14 hours ago













stackoverflow.com/questions/14116003/…

– Brandon Lyons
14 hours ago





stackoverflow.com/questions/14116003/…

– Brandon Lyons
14 hours ago












2 Answers
2






active

oldest

votes


















36














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.






share|improve this answer

































    10














    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|improve this answer



















    • 1





      I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

      – Eljay
      14 hours ago











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54258241%2fwarning-iso-c-forbids-converting-a-string-constant-to-char-for-a-static-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    36














    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.






    share|improve this answer






























      36














      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.






      share|improve this answer




























        36












        36








        36







        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.






        share|improve this answer















        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 13 hours ago









        Remy Lebeau

        332k18251446




        332k18251446










        answered 14 hours ago









        NathanOliverNathanOliver

        89.3k15121188




        89.3k15121188

























            10














            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|improve this answer



















            • 1





              I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

              – Eljay
              14 hours ago
















            10














            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|improve this answer



















            • 1





              I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

              – Eljay
              14 hours ago














            10












            10








            10







            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|improve this answer













            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|improve this answer












            share|improve this answer



            share|improve this answer










            answered 14 hours ago









            SergeyASergeyA

            42.1k53784




            42.1k53784








            • 1





              I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

              – Eljay
              14 hours ago














            • 1





              I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

              – Eljay
              14 hours ago








            1




            1





            I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

            – Eljay
            14 hours ago





            I remember the rule const binds to the thing to its immediate left (unless its first, in which case it binds to the thing to its immediate right). In my code, I tend to favor the general case, rather than the except-to-the-general rule in the parentheses. constexpr, when I use it (not frequently), I always put on the left as the first thing. I've not been bitten by the OP's situation yet.

            – Eljay
            14 hours ago


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54258241%2fwarning-iso-c-forbids-converting-a-string-constant-to-char-for-a-static-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to label and detect the document text images

            Tabula Rosettana

            Aureus (color)