Constexpr if with a non-bool condition












7















I seem to have found something that clang and gcc disagree on. Here's the code:



int main() {
if constexpr (2) {}
}


This successfully compiles with gcc 7.4.0 but fails with clang 7.0.0 with this error message:



test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
[-Wc++11-narrowing]
if constexpr (2) {}
^
1 error generated.


cppreference doesn't seem to mention "narrowing" so this seems like a clang bug but I'm not entirely certain. If this is a bug with either compiler, has it already been reported?










share|improve this question























  • What if you do if constexpr (!!2) {} ?

    – Jesper Juhl
    1 hour ago











  • (!!2) will work, but 2 should work too.

    – ivan.ukr
    1 hour ago











  • I just checked. !!2 works with clang

    – Kerndog73
    1 hour ago
















7















I seem to have found something that clang and gcc disagree on. Here's the code:



int main() {
if constexpr (2) {}
}


This successfully compiles with gcc 7.4.0 but fails with clang 7.0.0 with this error message:



test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
[-Wc++11-narrowing]
if constexpr (2) {}
^
1 error generated.


cppreference doesn't seem to mention "narrowing" so this seems like a clang bug but I'm not entirely certain. If this is a bug with either compiler, has it already been reported?










share|improve this question























  • What if you do if constexpr (!!2) {} ?

    – Jesper Juhl
    1 hour ago











  • (!!2) will work, but 2 should work too.

    – ivan.ukr
    1 hour ago











  • I just checked. !!2 works with clang

    – Kerndog73
    1 hour ago














7












7








7








I seem to have found something that clang and gcc disagree on. Here's the code:



int main() {
if constexpr (2) {}
}


This successfully compiles with gcc 7.4.0 but fails with clang 7.0.0 with this error message:



test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
[-Wc++11-narrowing]
if constexpr (2) {}
^
1 error generated.


cppreference doesn't seem to mention "narrowing" so this seems like a clang bug but I'm not entirely certain. If this is a bug with either compiler, has it already been reported?










share|improve this question














I seem to have found something that clang and gcc disagree on. Here's the code:



int main() {
if constexpr (2) {}
}


This successfully compiles with gcc 7.4.0 but fails with clang 7.0.0 with this error message:



test.cpp:3:17: error: constexpr if condition evaluates to 2, which cannot be narrowed to type 'bool'
[-Wc++11-narrowing]
if constexpr (2) {}
^
1 error generated.


cppreference doesn't seem to mention "narrowing" so this seems like a clang bug but I'm not entirely certain. If this is a bug with either compiler, has it already been reported?







c++ language-lawyer c++17 implicit-conversion compiler-bug






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 1 hour ago









Kerndog73Kerndog73

577724




577724













  • What if you do if constexpr (!!2) {} ?

    – Jesper Juhl
    1 hour ago











  • (!!2) will work, but 2 should work too.

    – ivan.ukr
    1 hour ago











  • I just checked. !!2 works with clang

    – Kerndog73
    1 hour ago



















  • What if you do if constexpr (!!2) {} ?

    – Jesper Juhl
    1 hour ago











  • (!!2) will work, but 2 should work too.

    – ivan.ukr
    1 hour ago











  • I just checked. !!2 works with clang

    – Kerndog73
    1 hour ago

















What if you do if constexpr (!!2) {} ?

– Jesper Juhl
1 hour ago





What if you do if constexpr (!!2) {} ?

– Jesper Juhl
1 hour ago













(!!2) will work, but 2 should work too.

– ivan.ukr
1 hour ago





(!!2) will work, but 2 should work too.

– ivan.ukr
1 hour ago













I just checked. !!2 works with clang

– Kerndog73
1 hour ago





I just checked. !!2 works with clang

– Kerndog73
1 hour ago












2 Answers
2






active

oldest

votes


















6














Clang is diagnosing under these paragraphs




[stmt.if] (emphasis mine)



2 If the if statement is of the form if constexpr, the value of
the condition shall be a contextually converted constant expression of
type bool
; this form is called a constexpr if statement.



[expr.const]



4 A converted constant expression of type T is an expression,
implicitly converted to type T, where the converted expression is a
constant expression and the implicit conversion sequence contains only




  • integral conversions other than narrowing conversions,




Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.



But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.





1 - And a proposal exists to change it, courtesy of Rakete1111 - https://wg21.link/p1401






share|improve this answer


























  • A bug in the standard! LOL

    – Kerndog73
    58 mins ago






  • 1





    There is a proposal for this, P1401

    – Rakete1111
    6 mins ago











  • @Rakete1111 - shamelessly added to the answer :) Thank you!

    – StoryTeller
    2 mins ago





















3














We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.



Clang is correct.






share|improve this answer























    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%2f54899466%2fconstexpr-if-with-a-non-bool-condition%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









    6














    Clang is diagnosing under these paragraphs




    [stmt.if] (emphasis mine)



    2 If the if statement is of the form if constexpr, the value of
    the condition shall be a contextually converted constant expression of
    type bool
    ; this form is called a constexpr if statement.



    [expr.const]



    4 A converted constant expression of type T is an expression,
    implicitly converted to type T, where the converted expression is a
    constant expression and the implicit conversion sequence contains only




    • integral conversions other than narrowing conversions,




    Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.



    But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.





    1 - And a proposal exists to change it, courtesy of Rakete1111 - https://wg21.link/p1401






    share|improve this answer


























    • A bug in the standard! LOL

      – Kerndog73
      58 mins ago






    • 1





      There is a proposal for this, P1401

      – Rakete1111
      6 mins ago











    • @Rakete1111 - shamelessly added to the answer :) Thank you!

      – StoryTeller
      2 mins ago


















    6














    Clang is diagnosing under these paragraphs




    [stmt.if] (emphasis mine)



    2 If the if statement is of the form if constexpr, the value of
    the condition shall be a contextually converted constant expression of
    type bool
    ; this form is called a constexpr if statement.



    [expr.const]



    4 A converted constant expression of type T is an expression,
    implicitly converted to type T, where the converted expression is a
    constant expression and the implicit conversion sequence contains only




    • integral conversions other than narrowing conversions,




    Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.



    But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.





    1 - And a proposal exists to change it, courtesy of Rakete1111 - https://wg21.link/p1401






    share|improve this answer


























    • A bug in the standard! LOL

      – Kerndog73
      58 mins ago






    • 1





      There is a proposal for this, P1401

      – Rakete1111
      6 mins ago











    • @Rakete1111 - shamelessly added to the answer :) Thank you!

      – StoryTeller
      2 mins ago
















    6












    6








    6







    Clang is diagnosing under these paragraphs




    [stmt.if] (emphasis mine)



    2 If the if statement is of the form if constexpr, the value of
    the condition shall be a contextually converted constant expression of
    type bool
    ; this form is called a constexpr if statement.



    [expr.const]



    4 A converted constant expression of type T is an expression,
    implicitly converted to type T, where the converted expression is a
    constant expression and the implicit conversion sequence contains only




    • integral conversions other than narrowing conversions,




    Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.



    But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.





    1 - And a proposal exists to change it, courtesy of Rakete1111 - https://wg21.link/p1401






    share|improve this answer















    Clang is diagnosing under these paragraphs




    [stmt.if] (emphasis mine)



    2 If the if statement is of the form if constexpr, the value of
    the condition shall be a contextually converted constant expression of
    type bool
    ; this form is called a constexpr if statement.



    [expr.const]



    4 A converted constant expression of type T is an expression,
    implicitly converted to type T, where the converted expression is a
    constant expression and the implicit conversion sequence contains only




    • integral conversions other than narrowing conversions,




    Now, when it comes to integral conversions, a conversion to bool is listed as an integral conversion. And it is narrowing, in the strictest sense of the word, since a bool cannot represent all the values of an int. So the diagnostic is not without grounds.



    But I think it's also quite reasonable to consider the fact a conversion to bool is usually intended to check for "truthiness", and so the narrowing nature of it shouldn't matter. It looks like a minor bug in the standard1, with GCC taking the common-sense route, and Clang adhering to the dry letter of the law in the strictest sense.





    1 - And a proposal exists to change it, courtesy of Rakete1111 - https://wg21.link/p1401







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 2 mins ago

























    answered 1 hour ago









    StoryTellerStoryTeller

    99.9k12201271




    99.9k12201271













    • A bug in the standard! LOL

      – Kerndog73
      58 mins ago






    • 1





      There is a proposal for this, P1401

      – Rakete1111
      6 mins ago











    • @Rakete1111 - shamelessly added to the answer :) Thank you!

      – StoryTeller
      2 mins ago





















    • A bug in the standard! LOL

      – Kerndog73
      58 mins ago






    • 1





      There is a proposal for this, P1401

      – Rakete1111
      6 mins ago











    • @Rakete1111 - shamelessly added to the answer :) Thank you!

      – StoryTeller
      2 mins ago



















    A bug in the standard! LOL

    – Kerndog73
    58 mins ago





    A bug in the standard! LOL

    – Kerndog73
    58 mins ago




    1




    1





    There is a proposal for this, P1401

    – Rakete1111
    6 mins ago





    There is a proposal for this, P1401

    – Rakete1111
    6 mins ago













    @Rakete1111 - shamelessly added to the answer :) Thank you!

    – StoryTeller
    2 mins ago







    @Rakete1111 - shamelessly added to the answer :) Thank you!

    – StoryTeller
    2 mins ago















    3














    We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.



    Clang is correct.






    share|improve this answer




























      3














      We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.



      Clang is correct.






      share|improve this answer


























        3












        3








        3







        We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.



        Clang is correct.






        share|improve this answer













        We say it, but it's hidden. "contextually converted constant expression of type bool" is a standard term-of-art that excludes narrowing conversions.



        Clang is correct.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 1 hour ago









        T.C.T.C.

        107k14220326




        107k14220326






























            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%2f54899466%2fconstexpr-if-with-a-non-bool-condition%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

            CARDNET

            Boot-repair Failure: Unable to locate package grub-common:i386

            濃尾地震