To my surprise, std::runtime_error only has a const std::string& constructor, but no value constructor. Thus I am wondering if throw std::runtime_error("Temporary" + std::to_string(100)); is defined. After all we are creating an exception object that refers to a temporary object inside the scope of a function that immediately exits (as we throw out of it). Further investigation showed that while returning a constant reference to a temporary value immediately causes a segfault on my system, throwing one doesn't:
const std::string& undefined_behavior() {
return "Undefined " + std::to_string(1);
}
void test() {
throw std::runtime_error("Hello : " + std::to_string(2));
}
void test2() {
const std::string& ref = "Hello : " + std::to_string(3);
throw ref;
}
int main(int argc, char** argv) {
//std::cout << undefined_behavior() << std::endl;
try {
test();
} catch(const std::runtime_error& ex) {
std::cout << ex.what() << std::endl;
}
try {
test2();
} catch(const std::string& ref) {
std::cout << ref << std::endl;
}
}
On my system, undefined_behavior() crashes immediately but test() and test2() run fine.
While I know the call to undefined_behavior() is undefined behavior, is test() and test2() undefined? If not, do thrown values get a specfied treatment?
And if they are all undefined but happened to work on my computer by accident, what is the proper way to throw an exception with a variable message?