Contract checking#

Contract checking macros#

There are three contract checking modes that can be set at build time by defining the appropriate symbol. Each mode has a specific behavior for the contract checking at runtime as described in the table below:

Build mode

Symbol to be defined

Behavior

OFF

ASAP_CONTRACT_OFF

None of the conditions are enforced.

DEFAULT

ASAP_CONTRACT_DEFAULT

Default mode conditions are enforced and execution will abort if the contract is not honored. Audit mode conditions are ignored.

AUDIT

ASAP_CONTRACT_AUDIT

All conditions are enforced and execution will abort if the contract is not honored.

Default mode macros#

ASAP_EXPECT(...)#

Defines a precondition.

A precondition describes the function’s expectation of its arguments and/or the state of other objects upon entry into the function and is usually placed at the start of a function body.

The macro can be invoked in multiple forms depending on whether a detailed failure message needs to be printed when the condition fails and whether the assertion is in a function that returns a value or not.

The accompanying message is sent to an output stream before being printed to the standard error output. Therefore, it is possible to chain multiple message chunks using the << operator.

ASAP_EXPECT(cond,
    "failed, was expecting: " << expected << " but got: " << actual)

The default handler aborts when an assertion fails, but it can be customized not to do so. The macro always has a return statement, and therefore, if it is located in a function that requires a return value, such value can be specified in the macro. This is not needed if the function does not return a value.

ASAP_EXPECT(cond, "failed, and will return a default value",
Result:kDefault);

Note

The prediction is ignored if the contract checking build mode is OFF.

ASAP_ENSURE(...)#

Defines a post-condition.

A post-condition is a condition that a function should ensure for the return value and/or the state of objects upon exit from the function and is usually placed immediately before returning control to the caller of the function.

The macro can be invoked in multiple forms depending on whether a detailed failure message needs to be printed when the condition fails and whether the assertion is in a function that returns a value or not.

The accompanying message is sent to an output stream before being printed to the standard error output. Therefore, it is possible to chain multiple message chunks using the << operator.

ASAP_ENSURE(cond, "failed, was supposed to be: " << expected << " but is: "
<< actual)

The default handler aborts when an assertion fails, but it can be customized not to do so. The macro always has a return statement, and therefore, if it is located in a function that requires a return value, such value can be specified in the macro. This is not needed if the function does not return a value.

ASAP_ENSURE(cond, "failed, and will return a default value",
Result:kDefault);

Note

The post-condition is ignored if the contract checking build mode is OFF.

ASAP_ASSERT(...)#

Defines an assertion.

An assertion is a condition that should be satisfied where it appears in a function body and can be placed anywhere within the body of a function.

The macro can be invoked in multiple forms depending on whether a detailed failure message needs to be printed when the condition fails and whether the assertion is in a function that returns a value or not.

The accompanying message is sent to an output stream before being printed to the standard error output. Therefore, it is possible to chain multiple message chunks using the << operator.

ASAP_ASSERT(cond, "failed, was supposed to be: " << expected << " but is: "
<< actual)

The default handler aborts when an assertion fails, but it can be customized not to do so. The macro always has a return statement, and therefore, if it is located in a function that requires a return value, such value can be specified in the macro. This is not needed if the function does not return a value.

ASAP_ASSERT(cond, "failed, and will return a default value",
Result:kDefault);

Note

The assertion is ignored if the contract checking build mode is OFF.

ASAP_CONSTEXPR_ASSERT(...)#

Defines a constexpr assertion macro.

In a constexpr context, if the condition fails, the code fails to compile. In a non-constexpr context, if the condition fails, message is printed to error output and the application aborts.

The macro can be invoked in multiple forms depending on whether a detailed failure message needs to be printed when the condition fails and whether the assertion is in a function that returns a value or not.

The accompanying message is sent to an output stream before being printed to the standard error output. Therefore, it is possible to chain multiple message chunks using the << operator.

constexpr int divide(int a, int b)
{
  return ASAP_CONSTEXPR_ASSERT(b, "divide(): can't divide by zero"), a / b;
}

Note

The assertion is ignored if the contract checking build mode is OFF.

ASAP_ASSERT_UNREACHABLE(...)#

Defines an assertion macro for unreachable code.

If code marked with this macro is reached, message is printed to error output and the application aborts.

void Unreachable(int value)
{
  if (value == 5) {
    value += 2;
    (void)value;
  }
  ASAP_ASSERT_UNREACHABLE("unreachable code")
}

Note

The assertion is ignored if the contract checking build mode is OFF.

Audit mode macros#

ASAP_EXPECT_AUDIT(condition, message, return_value)#

Defines a precondition for the AUDIT contract checking mode.

A precondition describes the function’s expectation of its arguments and/or the state of other objects upon entry into the function and is usually placed at the start of a function body.

Note

The precondition is enforced only if the contract checking build mode is AUDIT.

Parameters:
  • condition – an expression, that specifies the predicate of the contract.

  • message – an optional description message.

  • return_value – an optional return value if the macro is in function that requires one.

ASAP_ENSURE_AUDIT(condition, message, return_value)#

Defines a post-condition for the AUDIT contract checking mode.

A post-condition is a condition that a function should ensure for the return value and/or the state of objects upon exit from the function and is usually placed immediately before returning control to the caller of the function.

Note

The post-condition is enforced only if the contract checking build mode is AUDIT.

Parameters:
  • condition – an expression, that specifies the predicate of the contract.

  • message – an optional description message.

  • return_value – an optional return value if the macro is in function that requires one.

ASAP_ASSERT_AUDIT(condition, message, return_value)#

Defines an assertion for the AUDIT contract checking mode.

An assertion is a condition that should be satisfied where it appears in a function body and can be placed anywhere within the body of a function.

Note

The assertion is enforced only if the contract checking build mode is AUDIT.

Parameters:
  • condition – an expression, that specifies the predicate of the contract.

  • message – an optional description message.

  • return_value – an optional return value if the macro is in function that requires one.

Violation Handler#

There is a single violation handler in the system. Its implementation, however, can be switched at runtime to install a custom handler.

auto asap::contract::GetViolationHandler() -> ViolationHandler&#

Obtain the single instance of the violation handler.

Note

This function is very lightweight and can be called as often as required. It is preferred to exclusively call it every time the violation handler is needed instead of storing the returned reference.

Returns:

a reference to the violation handler.

class ViolationHandler#

Interface for a violation handler which can switch its implementation at runtime.

We expect to have a single violation handler instance in the system, although its implementation can be changed at runtime. Therefore, the interface clearly deletes the copy constructors and assignment operators.

Subclassed by asap::contract::ViolationHandler_impl

Public Types

using WrapperType = std::function<void(const Violation*)>#

A wrapper using std::function around violation handler implementation functions.

Public Functions

ViolationHandler() = default#

Constructor.

virtual ~ViolationHandler()#

Destructor.

ViolationHandler(const ViolationHandler&) = delete#

Copy constructor (deleted).

ViolationHandler(ViolationHandler&&) = default#

Move constructor (default)

auto operator=(const ViolationHandler&) -> ViolationHandler& = delete#

Copy assignment operator (deleted)

auto operator=(ViolationHandler&&) -> ViolationHandler& = default#

Move assignment operator (default)

virtual void HandleViolation(const Violation *violation) = 0#

Handle a contract violation.

This method is called when a contract violation occurs. The information related to the violation is provided by the violation parameter.

Note

This function may never return.

Parameters:

violation – violation details. Will never be null and is allocated on the stack.

virtual void SwapHandler(WrapperType &other_handler) = 0#

Swap the existing violation handler implementation with the give one.

Parameters:

other_handler – at the call time this holds the new violation handler implementation function. Upon return, it will hold the old violation handler function.