diff --git a/docs/en/api-guides/error-handling.rst b/docs/en/api-guides/error-handling.rst index 86277266b5..42c5e7985e 100644 --- a/docs/en/api-guides/error-handling.rst +++ b/docs/en/api-guides/error-handling.rst @@ -10,13 +10,13 @@ Overview Identifying and handling run-time errors is important for developing robust applications. There can be multiple kinds of run-time errors: - Recoverable errors: - + - Errors indicated by functions through return values (error codes) - C++ exceptions, thrown using ``throw`` keyword - Unrecoverable (fatal) errors: - - - Failed assertions (using ``assert`` macro and equivalent methods) and ``abort()`` calls. + + - Failed assertions (using ``assert`` macro and equivalent methods, see :ref:`assertions`) and ``abort()`` calls. - CPU exceptions: access to protected regions of memory, illegal instruction, etc. - System level checks: watchdog timeout, cache access error, stack overflow, stack smashing, heap corruption, etc. @@ -43,6 +43,8 @@ Additionally, :cpp:func:`esp_err_to_name_r` function will attempt to interpret t This feature is enabled by default, but can be disabled to reduce application binary size. See :ref:`CONFIG_ESP_ERR_TO_NAME_LOOKUP`. When this feature is disabled, :cpp:func:`esp_err_to_name` and :cpp:func:`esp_err_to_name_r` are still defined and can be called. In this case, :cpp:func:`esp_err_to_name` will return ``UNKNOWN ERROR``, and :cpp:func:`esp_err_to_name_r` will return ``Unknown error 0xXXXX(YYYYY)``, where ``0xXXXX`` and ``YYYYY`` are the hexadecimal and decimal representations of the error code, respectively. +.. _esp-error-check-macro: + ``ESP_ERROR_CHECK`` macro ------------------------- diff --git a/docs/en/contribute/style-guide.rst b/docs/en/contribute/style-guide.rst index f7dc397b86..8e2376f1b8 100644 --- a/docs/en/contribute/style-guide.rst +++ b/docs/en/contribute/style-guide.rst @@ -217,6 +217,46 @@ Enums should be defined through the `typedef` and be namespaced:: MODULE_FOO_THREE } module_foo_t; + +.. _assertions: + +Assertions +^^^^^^^^^^ + +The standard C ``assert()`` function, defined in ``assert.h`` should be used to check conditions that should be true in source code. In the default configuration, an assert condition that returns ``false`` or 0 will call ``abort()`` and trigger a :doc:`Fatal Error`. + +``assert()`` should only be used to detect unrecoverable errors due to a serious internal logic bug or corruption, where it's not possible for the program to continue. For recoverable errors, including errors that are possible due to invalid external input, an :doc:`error value should be returned `. + +.. note:: + + When asserting a value of type ``esp_err_t``is equal to ``ESP_OK``, use the :ref:`esp-error-check-macro` instead of an ``assert()``. + +It's possible to configure ESP-IDF projects with assertions disabled (see :ref:`CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL`). Therefore, functions called in an ``assert()`` statement should not have side-effects. + +It's also necessary to use particular techniques to avoid "variable set but not used" warnings when assertions are disabled, due to code patterns such as:: + + int res = do_something(); + assert(res == 0); + +Once the ``assert`` is optimized out, the ``res`` value is unused and the compiler will warn about this. However the function ``do_something()`` must still be called, even if assertions are disabled. + +When the variable is declared and initialized in a single statement, a good strategy is to cast it to ``void`` on a new line. The compiler will not produce a warning, and the variable can still be optimized out of the final binary:: + + int res = do_something(); + assert(res == 0); + (void)res; + +If the variable is declared separately, for example if it is used for multiple assertions, then it can be declared with the GCC attribute ``__attribute__((unused))``. The compiler will not produce any unused variable warnings, but the variable can still be optimized out:: + + int res __attribute__((unused)); + + res = do_something(); + assert(res == 0); + + res = do_something_else(); + assert(res != 0); + + C++ Code Formatting -------------------