'enum/integral casting from throw/catch?
As I understand it, the exception system in C++ doesn't implicitly cast to/from types that can be cast without issue, and I'd assume this is for more strict debugging; if you're throwing a bool, you may not want it to be caught in a statement where int is the exception type. This makes it particularly tricky for me to do the following:
enum Exception {
Flag1 = 1, // 0b00000001
Flag2 = 2, // 0b00000010
Flag3 = 4, // 0b00000100
Flag4 = 8 // 0b00001000
// And so on...
};
void doSomeStuff() {
// Theoretical code happens here
throw Flag1;
}
int main() {
try {
doSomeStuff();
} catch (Exception exception) {
if (exception & Flag1) {
std::cout << "Flag 1 is fatal" << std::endl;
return exception;
}
if (exception & Flag2) std::cout << "Flag 2 is non-fatal" << std::endl;
if (exception & Flag3) std::cout << "Flag 3 is non-fatal" << std::endl;
if (exception & Flag4) {
std::cout << "Flag 4 is fatal" << std::endl;
return exception;
}
}
return 0;
}
It all works just fine when I'm only using 1 flag at a time, but once I throw anything that's been OR'd (e.g. throw Flag1 | Flag2;), it no longer "fits inside" the enum and terminates.
terminate called after throwing an instance of 'int'
The fix for this is seemingly simple -- change catch (Exception exception) to catch (int exception), because enum values are always convertible to integrals, but not the other way around. However, when I throw an enum value on its own, I now get the same error but in reverse.
terminate called after throwing an instance of 'Exception'
I can think of 3 possible fixes:
- Explicitly cast to int every time I throw (the code that I'm actually trying to do this with is a very generic callback; could be run for dozens of different functions. Gross!)
- Have duplicate
catch(){}statements (because I am only sometimes returning frommain()depending on the flags of the value thrown, I can't put this into its own function; even more gross) - Instead of an
enum, use constants; probably just as fast (they both compile to literals), but less organized and should be completely unnecessary.
Are these my only options, or am I missing something?
Solution 1:[1]
Not tested but I think that Flag1 | Flag2 is considered by compiler as an int and not as a Exception
try casting the ored values before throwing
throw (int)(Flag1 | Flag2);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Gian Paolo |
