ice icon indicating copy to clipboard operation
ice copied to clipboard

C++ exception "what" refactoring

Open bernardnormier opened this issue 1 year ago • 0 comments

std::exception::what is a virtual function that returns a const char*. A difficulty is where to store this message. We currently store it in IceUtil::Exception where it's computed lazily:

https://github.com/zeroc-ice/ice/blob/c962e53fd5613d4fe036f60bcaec3c75e00d7c78/cpp/src/IceUtil/UtilException.cpp#L523

This proposal gets rid of this lazy computation, by computing the what message in the constructor of the "derived" exception:

Step 1:

  • change ice_staticId() and ice_id() to return a const char* (not a string_view or string).
  • it's an easy change since all these ids are string literals

Step 2:

  • change Ice::Exception::what() to return ice_id()

Step 3:

  • if an exception wants a custom message, it creates its own private
string _what;

field and fills in its constructor using its own private non-virtual ice_print helper function. For example:

class BadMagicException : public ProtocolException
{
public:
    // don't inherit base constructor(s)
    BadMagicException(const char* file, int line, std::string reason, ByteSeq badMagic) // no longer noexcept?
            : ProtocolException(file, line, std::move(reason)),
              badMagic(std::move(badMagic))  // should be out of line
    {
          ostringstream os;
          ice_print(os);
          _what = os.str();
    }    

    static const char* ice_staticId() { return "::Ice::BadMagicException"; }  // should be out of line

    const char* ice_id() const noexcept override { return ice_staticId(); }   // should be out of line
    const char* what() const  noexcept override { return _what; }  // should be out of line
 
    const string reason; // now const
    const ByteSeq badMagic; 
   
private:
    void ice_print(std::ostream&) { ... "prints" custom message } // should be out of line

    std::string _what; // stores the custom message for this class
};

For user exceptions, this proposal maintains compatibility with the existing cpp:ice_print metadata.

bernardnormier avatar Mar 15 '24 14:03 bernardnormier