How to deal with -Wreturn-type for switch over C++11 enum class?
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
add a comment |
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
2
throw after the switch?
– RiaD
Nov 13 '18 at 14:04
add a comment |
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
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
c++ enums gcc-warning
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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!
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 13 '18 at 14:47
gezageza
12.9k32776
12.9k32776
add a comment |
add a comment |
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!
add a comment |
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!
add a comment |
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!
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!
answered Nov 13 '18 at 14:11
Lightness Races in OrbitLightness Races in Orbit
288k51468796
288k51468796
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
throw after the switch?
– RiaD
Nov 13 '18 at 14:04