2

For the following example class, what are the exception safety guarantees for the getter methods?

Do such getter methods offer a minimum of a strong guarantee?

Does returning a fundamental type by value always offer a no throw guarantee?

class Foo
{
public:

    // TODO: Constructor

    // Getter methods
    int getA() const { return a; }
    std::string getB() const { return b; }
    std::vector<int> getC() const { return c; }
    Bar getD() const { return d; }
    std::vector<Bar> getE() const { return e; }

protected:
    int a;
    std::string b;
    std::vector<int> c;
    Bar d;
    std::vector<Bar> e;
}
Class Skeleton
  • 2,913
  • 6
  • 31
  • 51

2 Answers2

3

There are no guarantees of exception safety at all.

For example, getA() might throw an exception if a is not initialised (or do anything else for that matter since the behaviour would be undefined). Some chips (e.g. Itanium) do signal if an unitialised variable is read.

getC() could throw std::bad_alloc if you're low on memory. Ditto getB(), getD() and getE().

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Even if getB would be no except it could throw bad_alloc. Fyi – Alexander Oh Sep 25 '15 at 09:07
  • 2
    I understand what you are saying about for `getA()` - to never throw I need to make sure constructors (inc. copy and move) always initialise `a`. However, if any getter throws an exception won't this be classed as a strong guarantee because the state of the class has not been modified? – Class Skeleton Sep 25 '15 at 10:22
2

I think that all of your operations satisfy Strong exception safety, provided (where relevant) that the Bar(const Bar&) copy constructor is strongly safe. Additionally, getA will satisfy the nothrow guarantee, provided that a is initialised, e.g. in the constructor.

No part of Foo is modified by these const methods, so the main concern is leakage of the newly-created vectors - these should be deallocated automatically if there's an exception in copying the members from c or e to the return value.

The reason that a must be initialised properly is that copying uninitialised data may throw on architectures such as Itanium, as described in Bathsheba's answer.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103