Rule A15-4-5 (required, implementation, automated)
Checked exceptions that could be thrown from a function shall be specified together with the function declaration and they shall be identical in all function declarations and for all its overriders.
Rationale
In C++ language, all exceptions are unchecked, because the compiler does not force to either handle the exception or specify it. Because dynamic-exception specification is obsolete and error prone, an alternative mechanism of specifying checked exceptions using C++ comments along with function declarations is used. It is a concept that is based on Java exception handling mechanism. When analyzing a given function f, a static code analysis needs to analyze functions invoked by f and analyze if they throw any checked exceptions that are not caught by f and not listed by f in the function comment.
Exception
Within generic code, it is not generally possible to know what types of exceptions may be thrown from operations on template arguments, so a precise exception specification cannot be written. Therefore, this rule does not apply for templates.
Example
//% $Id: A15-4-5.cpp 309502 2018-02-28 09:17:39Z michal.szczepankiewicz $
#include <cstdint>
#include <stdexcept>
/// @checkedException
class CommunicationError : public std::exception
{
// Implementation
};
/// @checkedException
class BusError : public CommunicationError
{
// Implementation
};
/// @checkedException
class Timeout : public std::runtime_error
{
public:
using std::runtime_error::runtime_error;
// Implementation
};
/// @throw CommunicationError Communication error
/// @throw BusError Bus error
/// @throw Timeout
On send timeout exception
void Send1(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Compliant - All and only
// those checked exceptions
// that can be thrown are
// specified
{
// ...
throw CommunicationError();
// ...
throw BusError();
// ...
throw Timeout("Timeout reached");
// ...
}
/// @throw CommunicationError Communication error
void Send2(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Non-compliant - checked
// exceptions
// thrown are
// specification
{
// ...
throw CommunicationError();
// ...
throw Timeout("Timeout reached");
// ...
}
class MemoryPartitioningError : std::exception
{
// Implementation
};
/// @throw CommunicationError Communication error
that can be
missing from
/// @throw BusError Bus error
/// @throw Timeout
On send timeout exception
/// @throw MemoryPartitioningError Memory partitioning error prevents message
/// from being sent.
void Send3(
std::uint8_t* buffer,
std::uint8_t bufferLength) noexcept(false) // Non-compliant - additional
// checked exceptions are
// specified
{
// ...
throw CommunicationError();
// ...
throw Timeout("Timeout reached");
// ...
}
See also
Effective Java 2nd Edition [15]: Item 62: Document all exceptions thrown by each method