Q: C++ throwing exceptions (need advices) I was reading The C++ Programming Language by bjarne Stroustrup, especially chapters about exception safety and RAII programming idiom. I am familiar with RAII, but not with the throw of exceptions. Actually, I do not see the throw keyword used very often. I saw it sparingly (vector, red/black tree, ...) when I studied the Standard Template Library in order to understand the template mechanisms and the RAII idiom.
If I was to use the throw keyword, I would be tended to use it all the time. Thus, this syntax implies the use of the try-catch clauses which make the code looks ugly.
What do you think about this? Are there better techniques to handle exceptions? Or should I absolutely use throw?
Thanks for your responses. 

A: First of all, these links might help a bit.
Link 1
Link 2
Most of the time, C++ exceptions are better suited that any alternative. And actually, I think it makes the code prettier. I will give you an example, and I hope you understand.
Assume I have to load a model, and prepare it to be rendered(I know you probably are not familiar with graphics programming, but you should get the point) on the screen. This means I have a big function or at least a big one that calls a couple of other smaller ones. The whole process includes opening a model file, reading all coordinates, opening material files, allocating memory for materials, opening texture files, allocating memory for textures, loading the texture etc. A lot of stuff.
But sometimes, at the very end, I might encounter an error where I cannot find one of the texture files, or cannot open it. How to handle it? Have the small file open function return a value to the texture loading function who checks it, realizes something bad happened and in turn returns something to the function that read the main model file etc? Don't you think all that returning, checking and freeing resources at each point looks ugly?
Here is a better way: wrap the load_model() function in a try block, and just insert some throw statements wherever you need them. And have all the "free memory" code in the catch section. It will look a lot cleaner, and is also less likely you will make a mistake.
I hope you understand the idea. If you have any questions, please ask them.

A: I only use throw when I have a function that must return something and I can. When I return pointers, a null pointer is enough, but when returning references, there's nothing you can return, thus I throw. A part of that, I never throw, and I never catch too, because of the reason you told.
There are better thing to come to C++ with error handling. First of all, there's function contract to come in later C++ versions. It will allow you to do this:
struct Database {
    SomeResult query(std::string) [[expect: connected]] {
        // ...
    }

private:
    bool connected = false;
};

And the error handler is customizable, so it might be exception, and it might be std::terminate.

There is the std::expected proposal too. This is an utility you can use right now with boost implementation.
It would allow function to either return a result, either return an error. The user of the function can then handle it correctly, in a much more beautiful way than catch. Consider this example, taken from the proposal:

With expected, we are not required to use exceptions, we can use
  std::error_condition which is easier to introspect than
  std::exception_ptr if we want to use the error. For the purpose of
  this example, we use the following enumeration (the boilerplate code
  concerning std::error_condition is not shown):
enum class arithmetic_errc
{
    divide_by_zero, // 9/0 == ?
    not_integer_division // 5/2 == 2.5 (which is not an integer)
};

Using expected, the code becomes:
expected<double,error_condition> safe_divide(double i, double j)
{
    if (j==0) return make_unexpected(arithmetic_errc::divide_by_zero); // (1)
    else return i / j; // (2)
}


In the proposal, it shows that you can change user functions like this:

For instance, the exception-based function i + j/k is:
double f1(double i, double j, double k)
{
    return i + safe_divide(j,k);
}

but becomes using expected:
expected<double, error_condition> f1(double i, double j, double k)
{
    auto q = safe_divide(j, k)
    if(q) return i + *q;
    else return q;
}


And it shows later that you could write a shorten version of this too, using std::expected::map:

expected<double, error_condition> f1(double i, double j, double k)
{
    return safe_divide(j, k).map([&](double q){
        return i + q;
    });
}


You can read about both proposal here: Simple Contact for C++ and std::expected proposal

A: Exceptions are great for handling exceptional cases:


*

*Errors that prevent a constructor to finish its job.   

*Errors that are not expected to happen.  A typical example is memory allocation issues

*Errors that potentially would cascade because they indicate a clearly adverse situation 


However exceptions should not be used when the error is not exceptional, i.e. it is expected to happen regularly (for example looping until a condition happens).  In such cases, a special return value is a better option.  
The reason is threefold:  


*

*conceptual: the word "exception" strongly suggest en exceptional circumstance. 

*performance: with modern compilers entering a try bloc has almost no noticeable performance impact: it's a very cheap protection. But when you throw, there is obviously a stack unwinding effort that is much more costly than returning some values ("much more costly" is however still faster than displaying a message though... for an order of magnitude: about 7µs for a throw on my old i7 cpu, compared to a nanosecond level for an equivalent return) 

*robustness: if an object that is destroyed as part of stack unwinding throws itself an exception, the exception processing terminate() your program abruptly.  This would be a very unlikely situation. However if you abuse of exception handling and use it in almost normal situation as substitute for returning, you increase the probability of being one day in such a situation unless you'd take extreme care.  

