Looking at some old code we have lots of things like the following:
// This is dumb
string do_something(int in)
{
stringstream out;
try
{
out << std::fixed << in;
}
catch(std::exception &e)
{
out << e.what();
}
return out.str();
}
// Can't we just do this? Can this ever fail?
string do_something_better(int in)
{
stringstream out;
out << std::fixed << in;
return out.str();
}
When a stringstream reads a primitive can it ever throw an exception? What about when reading a string?
Summarizing a few answers
By default, streams don't throw exceptions. They can if they are enabled.
stringstream out;
out.exceptions(std::ios::failbit); // throw exception if failbit gets set
According to the Apache C++ Standard Library User's Guide
The flag std::ios_base::badbit indicates problems with the underlying stream buffer. These problems could be:
Memory shortage. There is no memory available to create the buffer, or the buffer has size 0 for other reasons (such as being provided from outside the stream), or the stream cannot allocate memory for its own internal data, as with std::ios_base::iword() and std::ios_base::pword().
The underlying stream buffer throws an exception. The stream buffer might lose its integrity, as in memory shortage, or code conversion failure, or an unrecoverable read error from the external device. The stream buffer can indicate this loss of integrity by throwing an exception, which is caught by the stream and results in setting the badbit in the stream's state.
Generally, you should keep in mind that badbit indicates an error situation that is likely to be unrecoverable, whereas failbit indicates a situation that might allow you to retry the failed operation.
So it seems like the safest way to do this would be
string do_something(int in)
{
stringstream out; // This could throw a bad_alloc
out << std::fixed << in; // This could set bad or fail bits
if(out.good())
{
return out.str();
}
else
{
return "";
}
}
This is overkill though because according to Handling bad_alloc if creating the stream fails, there are bigger problems to worry about, and the program is probably going to exit. So assuming it gets past creating the stream, it's possible but extremely unlikely that the badbit gets set. (Stream gets allocated with memory < sizeof(int)).
It's also unlikely that the failbit gets set (not sure of a use case for reading off the stack other than a corrupt stack). So the following code is sufficient, as recovering from a stream error at this point is unlikley.
string do_something(int in)
{
stringstream out;
out << std::fixed << in;
return out.str();
}