Triskeldeian
Triskeldeian

Reputation: 628

Polymorphic exception handling and compiler warnings

I have a small issue I'm not able to solve in a clean way. I'm experimenting a bit with polymorphic exception handling, so I added a raise virtual function in my exception class that do the actual throwing and I replaced the throw with a raise() call. Everything works as expected but then I applied this solution to a function with a return type with the following general form:

Obj Foo()
{
  if(true)
    return Obj
  else
  {
    //throw Exception; //With this call everything is fine
    Exception e{};
    e.raise(); //The compiler warns me that I do not return anything
  }
}

When I compile such a function the GCC compiler (v4.9) complains that Foo reaches the end without returning (-Wreturn-type) Is there a way to convince the compiler that everything is ok, without hiding the warning away?

Upvotes: 0

Views: 755

Answers (3)

Ami Tavory
Ami Tavory

Reputation: 76366

To avoid this, you can make each control path in the function return something that agrees with the return type, even if some conditionals can be shown to always be valid, or some paths can be shown to always throw exceptions. Here, your else path has no Obj-type return value.

Thus, after your e.raise(), you can return some value. If it is not possible to create a suitable value, consider making your function return optional<obj>.

Upvotes: 1

Peter
Peter

Reputation: 36617

I assume that Exception.raise() throws an exception and that you are using true to represent some expression that determines if an exception is not to be thrown (rather than the C++ keyword). (since you have not mentioned the compiler complaining about a condition that is always true).

The obvious solution is to add a return statement after throwing the exception.

Exception e{};
e.raise();
return Obj;    // this will not be reached

Another option is to restructure your code so there is always a return path

if (!true)
{
     Exception e{};
     e.raise();       // or, alternatively, throw e
}
return Obj;

This way, for every execution path the compiler can detect, there is a valid return statement.

Upvotes: 2

Sam Varshavchik
Sam Varshavchik

Reputation: 118445

If you do not need portability, and using gcc's compiler extensions are fine, then you can use the gcc noreturn function attribute, which works with C and C++ functions:

class Exception {

// ...

   void raise() __attribute__ ((noreturn));

};

Upvotes: 1

Related Questions