Why do these two pieces of code using constexpr, __PRETTY_FUNCTION__ and char * have different results?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
1












I have this code where if you comment out the line commented "But this doesn't work?!" it compiles just fine, but if you don't, the compiler generates an error.



At least, gcc 8.2 generates an error.



But, they seem identical to me. What's the problem? Is this legal code at all?



template <int x>
struct test_template
static int size() return x;
;

constexpr int ce_strlen(char const *s)

int i = 0;
while (s[i]) ++i;
return i;


int joe()

constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works
test_template<plen> a; // This declaration is valid.
test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn't work?!
return a.size() + b.size();



I ran into this while trying to come up with a way to create profile tags for an intrusive profiling system at compile time. I succeeded, but my final code does not involve using ce_strlen.










share|improve this question



















  • 1




    Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
    – aschepler
    3 hours ago










  • @aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
    – Omnifarious
    3 hours ago







  • 2




    Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
    – Barry
    3 hours ago






  • 4




    Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
    – Barry
    3 hours ago










  • According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
    – Aconcagua
    2 hours ago














up vote
8
down vote

favorite
1












I have this code where if you comment out the line commented "But this doesn't work?!" it compiles just fine, but if you don't, the compiler generates an error.



At least, gcc 8.2 generates an error.



But, they seem identical to me. What's the problem? Is this legal code at all?



template <int x>
struct test_template
static int size() return x;
;

constexpr int ce_strlen(char const *s)

int i = 0;
while (s[i]) ++i;
return i;


int joe()

constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works
test_template<plen> a; // This declaration is valid.
test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn't work?!
return a.size() + b.size();



I ran into this while trying to come up with a way to create profile tags for an intrusive profiling system at compile time. I succeeded, but my final code does not involve using ce_strlen.










share|improve this question



















  • 1




    Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
    – aschepler
    3 hours ago










  • @aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
    – Omnifarious
    3 hours ago







  • 2




    Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
    – Barry
    3 hours ago






  • 4




    Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
    – Barry
    3 hours ago










  • According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
    – Aconcagua
    2 hours ago












up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






1





I have this code where if you comment out the line commented "But this doesn't work?!" it compiles just fine, but if you don't, the compiler generates an error.



At least, gcc 8.2 generates an error.



But, they seem identical to me. What's the problem? Is this legal code at all?



template <int x>
struct test_template
static int size() return x;
;

constexpr int ce_strlen(char const *s)

int i = 0;
while (s[i]) ++i;
return i;


int joe()

constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works
test_template<plen> a; // This declaration is valid.
test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn't work?!
return a.size() + b.size();



I ran into this while trying to come up with a way to create profile tags for an intrusive profiling system at compile time. I succeeded, but my final code does not involve using ce_strlen.










share|improve this question















I have this code where if you comment out the line commented "But this doesn't work?!" it compiles just fine, but if you don't, the compiler generates an error.



At least, gcc 8.2 generates an error.



But, they seem identical to me. What's the problem? Is this legal code at all?



template <int x>
struct test_template
static int size() return x;
;

constexpr int ce_strlen(char const *s)

int i = 0;
while (s[i]) ++i;
return i;


int joe()

constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works
test_template<plen> a; // This declaration is valid.
test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn't work?!
return a.size() + b.size();



I ran into this while trying to come up with a way to create profile tags for an intrusive profiling system at compile time. I succeeded, but my final code does not involve using ce_strlen.







c++ gcc c++17 constexpr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago

























asked 3 hours ago









Omnifarious

39.2k1196153




39.2k1196153







  • 1




    Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
    – aschepler
    3 hours ago










  • @aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
    – Omnifarious
    3 hours ago







  • 2




    Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
    – Barry
    3 hours ago






  • 4




    Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
    – Barry
    3 hours ago










  • According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
    – Aconcagua
    2 hours ago












  • 1




    Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
    – aschepler
    3 hours ago










  • @aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
    – Omnifarious
    3 hours ago







  • 2




    Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
    – Barry
    3 hours ago






  • 4




    Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
    – Barry
    3 hours ago










  • According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
    – Aconcagua
    2 hours ago







1




1




Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
– aschepler
3 hours ago




Well, __PRETTY_FUNCTION__ isn't standard. (__func__ is, but may not be unique enough for your purposes, especially in the presence of overloads and templates.)
– aschepler
3 hours ago












@aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
– Omnifarious
3 hours ago





@aschepler - I believe there's been a movement to standardize something like __PRETTY_FUNCTION__. But, that's why I put in the gcc tag. :-) That and clang doesn't seem to have a problem with the code. Also, lambdas. Lambdas are a really interesting case here.
– Omnifarious
3 hours ago





2




2




Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
– Barry
3 hours ago




Given that ce_strlen returns an int, which is also the same type as test_template's non-type template parameter - there's no reason these should have different behavior. I struggle with [expr.const], but at least I'm pretty sure these should either both compile or both fail.
– Barry
3 hours ago




4




4




Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
– Barry
3 hours ago




Filed 87399. My best guess is that both should fail, but it's surely a bug that both behave differently.
– Barry
3 hours ago












According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
– Aconcagua
2 hours ago




According to gcc documentation, __PRETTY_FUNCTION__ is constexpr, so both cases should compile.
– Aconcagua
2 hours ago












1 Answer
1






active

oldest

votes

















up vote
6
down vote













Indeed this is a bug in GCC as discussed in the comments, but I thought I'd throw in some additional insight as to the nature of this bug. In the GCC NEWS file there is this line:





  • FUNCTION and PRETTY_FUNCTION are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")' must be rewritten toprintf ("%s: foo", FUNCTION)'. This is necessary for templates.



But __PRETTY_FUNCTION__ isn't really a variable, it's a special case treated in the parser as we see in constexpr.c:



 case DECL_EXPR:



If it really was a variable, we'd expect it to pass the same test cases as these:



constexpr const char* s2 = "TEST";
constexpr const char* s3 = s2;
test_template<ce_strlen("TEST")> c;
test_template<ce_strlen(s2)> d;
test_template<ce_strlen(s3)> e;





share|improve this answer








New contributor




user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    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',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    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%2f52472000%2fwhy-do-these-two-pieces-of-code-using-constexpr-pretty-function-and-char%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    6
    down vote













    Indeed this is a bug in GCC as discussed in the comments, but I thought I'd throw in some additional insight as to the nature of this bug. In the GCC NEWS file there is this line:





    • FUNCTION and PRETTY_FUNCTION are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")' must be rewritten toprintf ("%s: foo", FUNCTION)'. This is necessary for templates.



    But __PRETTY_FUNCTION__ isn't really a variable, it's a special case treated in the parser as we see in constexpr.c:



     case DECL_EXPR:



    If it really was a variable, we'd expect it to pass the same test cases as these:



    constexpr const char* s2 = "TEST";
    constexpr const char* s3 = s2;
    test_template<ce_strlen("TEST")> c;
    test_template<ce_strlen(s2)> d;
    test_template<ce_strlen(s3)> e;





    share|improve this answer








    New contributor




    user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      6
      down vote













      Indeed this is a bug in GCC as discussed in the comments, but I thought I'd throw in some additional insight as to the nature of this bug. In the GCC NEWS file there is this line:





      • FUNCTION and PRETTY_FUNCTION are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")' must be rewritten toprintf ("%s: foo", FUNCTION)'. This is necessary for templates.



      But __PRETTY_FUNCTION__ isn't really a variable, it's a special case treated in the parser as we see in constexpr.c:



       case DECL_EXPR:



      If it really was a variable, we'd expect it to pass the same test cases as these:



      constexpr const char* s2 = "TEST";
      constexpr const char* s3 = s2;
      test_template<ce_strlen("TEST")> c;
      test_template<ce_strlen(s2)> d;
      test_template<ce_strlen(s3)> e;





      share|improve this answer








      New contributor




      user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



















        up vote
        6
        down vote










        up vote
        6
        down vote









        Indeed this is a bug in GCC as discussed in the comments, but I thought I'd throw in some additional insight as to the nature of this bug. In the GCC NEWS file there is this line:





        • FUNCTION and PRETTY_FUNCTION are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")' must be rewritten toprintf ("%s: foo", FUNCTION)'. This is necessary for templates.



        But __PRETTY_FUNCTION__ isn't really a variable, it's a special case treated in the parser as we see in constexpr.c:



         case DECL_EXPR:



        If it really was a variable, we'd expect it to pass the same test cases as these:



        constexpr const char* s2 = "TEST";
        constexpr const char* s3 = s2;
        test_template<ce_strlen("TEST")> c;
        test_template<ce_strlen(s2)> d;
        test_template<ce_strlen(s3)> e;





        share|improve this answer








        New contributor




        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        Indeed this is a bug in GCC as discussed in the comments, but I thought I'd throw in some additional insight as to the nature of this bug. In the GCC NEWS file there is this line:





        • FUNCTION and PRETTY_FUNCTION are now treated as variables by the parser; previously they were treated as string constants. So code like printf (__FUNCTION__ ": foo")' must be rewritten toprintf ("%s: foo", FUNCTION)'. This is necessary for templates.



        But __PRETTY_FUNCTION__ isn't really a variable, it's a special case treated in the parser as we see in constexpr.c:



         case DECL_EXPR:



        If it really was a variable, we'd expect it to pass the same test cases as these:



        constexpr const char* s2 = "TEST";
        constexpr const char* s3 = s2;
        test_template<ce_strlen("TEST")> c;
        test_template<ce_strlen(s2)> d;
        test_template<ce_strlen(s3)> e;






        share|improve this answer








        New contributor




        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 2 hours ago









        user10405994

        611




        611




        New contributor




        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        user10405994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52472000%2fwhy-do-these-two-pieces-of-code-using-constexpr-pretty-function-and-char%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            What does second last employer means? [closed]

            One-line joke