#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>
// this function can throw anything
void foo(bool pThrow)
{
std::cout << "foo: " << pThrow << std::endl;
if (pThrow)
throw std::runtime_error("throwing foo");
}
// this function can throw std::runtime_error
void bar(bool pThrow) throw(std::runtime_error)
{
std::cout << "bar: " << pThrow << std::endl;
if (pThrow)
throw std::runtime_error("throwing bar");
}
// this function can't throw anything
void baz(bool pThrow) throw()
{
std::cout << "baz: " << pThrow << std::endl;
if (pThrow)
throw std::runtime_error("throwing baz");
// ^ may generate warning
}
void uh_oh(void)
{
std::cerr << "an exception-"
"specification was broken!" << std::endl;
// terminate() will be called
}
void goodbye(void)
{
std::cerr << "terminate!" << std::endl;
}
int main(void)
{
// if an exception that isn't allowed
// leaves a function, uh_oh is called
std::set_unexpected(uh_oh);
// if the program is terminated,
// goodbye is called
std::set_terminate(goodbye);
std::cout << std::boolalpha;
try
{
foo(false); // okay, nothing is thrown
foo(true); // okay, exception allowed
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
try
{
bar(false); // okay, nothing is thrown
bar(true); // okay, exception allowed
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
try
{
baz(false); // okay, nothing is thrown
baz(true); // not okay, exception disallowed
}
catch (const std::exception& e)
{
// will never be entered, exception
// cannot leave baz
std::cerr << e.what() << std::endl;
}
}