How to deal with -Wreturn-type for switch over C++11 enum class?












1















If I have a function that returns based on switching over a enum class, gcc emits warning: control reaches end of non-void function [-Wreturn-type]. Example code:



enum class Test { a, b, c } ;

int foo(Test test) {
switch (test) {
case Test::a: return 0;
case Test::b: return 1;
case Test::c: return 2;
}
}


I have thought of two solutions but neither seem correct:



1) have a default case that throws. However, when I add an additional member to the enum class I no longer receive an error that I missed a case.



2) Suppress the warning with a pragma, but then I don't guard against someone passing in a static_cast<Test>(123).



So my question is, how to deal with -Wreturn-type errors for switch over C++11 enum class?










share|improve this question




















  • 2





    throw after the switch?

    – RiaD
    Nov 13 '18 at 14:04
















1















If I have a function that returns based on switching over a enum class, gcc emits warning: control reaches end of non-void function [-Wreturn-type]. Example code:



enum class Test { a, b, c } ;

int foo(Test test) {
switch (test) {
case Test::a: return 0;
case Test::b: return 1;
case Test::c: return 2;
}
}


I have thought of two solutions but neither seem correct:



1) have a default case that throws. However, when I add an additional member to the enum class I no longer receive an error that I missed a case.



2) Suppress the warning with a pragma, but then I don't guard against someone passing in a static_cast<Test>(123).



So my question is, how to deal with -Wreturn-type errors for switch over C++11 enum class?










share|improve this question




















  • 2





    throw after the switch?

    – RiaD
    Nov 13 '18 at 14:04














1












1








1


1






If I have a function that returns based on switching over a enum class, gcc emits warning: control reaches end of non-void function [-Wreturn-type]. Example code:



enum class Test { a, b, c } ;

int foo(Test test) {
switch (test) {
case Test::a: return 0;
case Test::b: return 1;
case Test::c: return 2;
}
}


I have thought of two solutions but neither seem correct:



1) have a default case that throws. However, when I add an additional member to the enum class I no longer receive an error that I missed a case.



2) Suppress the warning with a pragma, but then I don't guard against someone passing in a static_cast<Test>(123).



So my question is, how to deal with -Wreturn-type errors for switch over C++11 enum class?










share|improve this question
















If I have a function that returns based on switching over a enum class, gcc emits warning: control reaches end of non-void function [-Wreturn-type]. Example code:



enum class Test { a, b, c } ;

int foo(Test test) {
switch (test) {
case Test::a: return 0;
case Test::b: return 1;
case Test::c: return 2;
}
}


I have thought of two solutions but neither seem correct:



1) have a default case that throws. However, when I add an additional member to the enum class I no longer receive an error that I missed a case.



2) Suppress the warning with a pragma, but then I don't guard against someone passing in a static_cast<Test>(123).



So my question is, how to deal with -Wreturn-type errors for switch over C++11 enum class?







c++ enums gcc-warning






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 14:09









Some programmer dude

297k24252414




297k24252414










asked Nov 13 '18 at 14:01









PeterPeter

204




204








  • 2





    throw after the switch?

    – RiaD
    Nov 13 '18 at 14:04














  • 2





    throw after the switch?

    – RiaD
    Nov 13 '18 at 14:04








2




2





throw after the switch?

– RiaD
Nov 13 '18 at 14:04





throw after the switch?

– RiaD
Nov 13 '18 at 14:04












2 Answers
2






active

oldest

votes


















1














Note: this answer is written with performance in mind (if you don't need it, just ignore this, and put some fatal error after the switch).



I'd recommend to use a compiler-specific feature to mark unreachable code. All major compilers have something like this. For example, GCC/Clang/icc has __builtin_unreachable, MSVC has __assume(false).



Use these tools in release mode. In debug mode, put some fatal error (assert, exception, whatever) there. This way, while in development, you'll catch errors, and in release mode, generated code will be efficient.



Note, there is a proposal, which intends to add std::unreachable() to C++. When this hopefully gets through, you can use it in such codes. Until then, you have to resort to the previously-mentioned compiler-specific solution.






share|improve this answer































    2














    Typically I will put something after the switch, be it a throw something() or a return -1. You need to ensure that, at runtime, a call to this function is at least safe no matter what happens. Your compiler is telling you as much.



    Example:



    enum class Test { a, b, c } ;

    int foo(Test test) {
    switch (test) {
    case Test::a: return 0;
    case Test::b: return 1;
    case Test::c: return 2;
    }

    throw std::runtime_error("Unhandled Test enumerator " + std::to_string((int)test) + " in foo()");
    }


    Ideally your customers will never see this but, if they do (by means of your top-level catch — you have one, right?), you know immediately what the problem is and can fix it.



    Additionally (but not solely) I will consider putting a debug assertion like assert (or project-specific equivalent) so that this bug is detected during development. (Though, in the example above with try, that would actually prevent generation of the useful error message, so it's not always appropriate.)



    Also if you turn on -Werror then fail to add an item to the switch, your project won't build anyway so that solves the problem at source (literally!).



    In general, don't ignore or try to suppress warnings: heed them!






    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%2f53282722%2fhow-to-deal-with-wreturn-type-for-switch-over-c11-enum-class%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









      1














      Note: this answer is written with performance in mind (if you don't need it, just ignore this, and put some fatal error after the switch).



      I'd recommend to use a compiler-specific feature to mark unreachable code. All major compilers have something like this. For example, GCC/Clang/icc has __builtin_unreachable, MSVC has __assume(false).



      Use these tools in release mode. In debug mode, put some fatal error (assert, exception, whatever) there. This way, while in development, you'll catch errors, and in release mode, generated code will be efficient.



      Note, there is a proposal, which intends to add std::unreachable() to C++. When this hopefully gets through, you can use it in such codes. Until then, you have to resort to the previously-mentioned compiler-specific solution.






      share|improve this answer




























        1














        Note: this answer is written with performance in mind (if you don't need it, just ignore this, and put some fatal error after the switch).



        I'd recommend to use a compiler-specific feature to mark unreachable code. All major compilers have something like this. For example, GCC/Clang/icc has __builtin_unreachable, MSVC has __assume(false).



        Use these tools in release mode. In debug mode, put some fatal error (assert, exception, whatever) there. This way, while in development, you'll catch errors, and in release mode, generated code will be efficient.



        Note, there is a proposal, which intends to add std::unreachable() to C++. When this hopefully gets through, you can use it in such codes. Until then, you have to resort to the previously-mentioned compiler-specific solution.






        share|improve this answer


























          1












          1








          1







          Note: this answer is written with performance in mind (if you don't need it, just ignore this, and put some fatal error after the switch).



          I'd recommend to use a compiler-specific feature to mark unreachable code. All major compilers have something like this. For example, GCC/Clang/icc has __builtin_unreachable, MSVC has __assume(false).



          Use these tools in release mode. In debug mode, put some fatal error (assert, exception, whatever) there. This way, while in development, you'll catch errors, and in release mode, generated code will be efficient.



          Note, there is a proposal, which intends to add std::unreachable() to C++. When this hopefully gets through, you can use it in such codes. Until then, you have to resort to the previously-mentioned compiler-specific solution.






          share|improve this answer













          Note: this answer is written with performance in mind (if you don't need it, just ignore this, and put some fatal error after the switch).



          I'd recommend to use a compiler-specific feature to mark unreachable code. All major compilers have something like this. For example, GCC/Clang/icc has __builtin_unreachable, MSVC has __assume(false).



          Use these tools in release mode. In debug mode, put some fatal error (assert, exception, whatever) there. This way, while in development, you'll catch errors, and in release mode, generated code will be efficient.



          Note, there is a proposal, which intends to add std::unreachable() to C++. When this hopefully gets through, you can use it in such codes. Until then, you have to resort to the previously-mentioned compiler-specific solution.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 14:47









          gezageza

          12.9k32776




          12.9k32776

























              2














              Typically I will put something after the switch, be it a throw something() or a return -1. You need to ensure that, at runtime, a call to this function is at least safe no matter what happens. Your compiler is telling you as much.



              Example:



              enum class Test { a, b, c } ;

              int foo(Test test) {
              switch (test) {
              case Test::a: return 0;
              case Test::b: return 1;
              case Test::c: return 2;
              }

              throw std::runtime_error("Unhandled Test enumerator " + std::to_string((int)test) + " in foo()");
              }


              Ideally your customers will never see this but, if they do (by means of your top-level catch — you have one, right?), you know immediately what the problem is and can fix it.



              Additionally (but not solely) I will consider putting a debug assertion like assert (or project-specific equivalent) so that this bug is detected during development. (Though, in the example above with try, that would actually prevent generation of the useful error message, so it's not always appropriate.)



              Also if you turn on -Werror then fail to add an item to the switch, your project won't build anyway so that solves the problem at source (literally!).



              In general, don't ignore or try to suppress warnings: heed them!






              share|improve this answer




























                2














                Typically I will put something after the switch, be it a throw something() or a return -1. You need to ensure that, at runtime, a call to this function is at least safe no matter what happens. Your compiler is telling you as much.



                Example:



                enum class Test { a, b, c } ;

                int foo(Test test) {
                switch (test) {
                case Test::a: return 0;
                case Test::b: return 1;
                case Test::c: return 2;
                }

                throw std::runtime_error("Unhandled Test enumerator " + std::to_string((int)test) + " in foo()");
                }


                Ideally your customers will never see this but, if they do (by means of your top-level catch — you have one, right?), you know immediately what the problem is and can fix it.



                Additionally (but not solely) I will consider putting a debug assertion like assert (or project-specific equivalent) so that this bug is detected during development. (Though, in the example above with try, that would actually prevent generation of the useful error message, so it's not always appropriate.)



                Also if you turn on -Werror then fail to add an item to the switch, your project won't build anyway so that solves the problem at source (literally!).



                In general, don't ignore or try to suppress warnings: heed them!






                share|improve this answer


























                  2












                  2








                  2







                  Typically I will put something after the switch, be it a throw something() or a return -1. You need to ensure that, at runtime, a call to this function is at least safe no matter what happens. Your compiler is telling you as much.



                  Example:



                  enum class Test { a, b, c } ;

                  int foo(Test test) {
                  switch (test) {
                  case Test::a: return 0;
                  case Test::b: return 1;
                  case Test::c: return 2;
                  }

                  throw std::runtime_error("Unhandled Test enumerator " + std::to_string((int)test) + " in foo()");
                  }


                  Ideally your customers will never see this but, if they do (by means of your top-level catch — you have one, right?), you know immediately what the problem is and can fix it.



                  Additionally (but not solely) I will consider putting a debug assertion like assert (or project-specific equivalent) so that this bug is detected during development. (Though, in the example above with try, that would actually prevent generation of the useful error message, so it's not always appropriate.)



                  Also if you turn on -Werror then fail to add an item to the switch, your project won't build anyway so that solves the problem at source (literally!).



                  In general, don't ignore or try to suppress warnings: heed them!






                  share|improve this answer













                  Typically I will put something after the switch, be it a throw something() or a return -1. You need to ensure that, at runtime, a call to this function is at least safe no matter what happens. Your compiler is telling you as much.



                  Example:



                  enum class Test { a, b, c } ;

                  int foo(Test test) {
                  switch (test) {
                  case Test::a: return 0;
                  case Test::b: return 1;
                  case Test::c: return 2;
                  }

                  throw std::runtime_error("Unhandled Test enumerator " + std::to_string((int)test) + " in foo()");
                  }


                  Ideally your customers will never see this but, if they do (by means of your top-level catch — you have one, right?), you know immediately what the problem is and can fix it.



                  Additionally (but not solely) I will consider putting a debug assertion like assert (or project-specific equivalent) so that this bug is detected during development. (Though, in the example above with try, that would actually prevent generation of the useful error message, so it's not always appropriate.)



                  Also if you turn on -Werror then fail to add an item to the switch, your project won't build anyway so that solves the problem at source (literally!).



                  In general, don't ignore or try to suppress warnings: heed them!







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 14:11









                  Lightness Races in OrbitLightness Races in Orbit

                  288k51468796




                  288k51468796






























                      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%2f53282722%2fhow-to-deal-with-wreturn-type-for-switch-over-c11-enum-class%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

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values