Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Wiki Markup
C99, Section 7.2.1.1, defines {{assert()}} to have the following behavior \[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\]:
<blockquote><p>The <code>assert</code> macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if <code>expression</code> (which shall have a scalar type) is false (that is, compares equal to 0), the <code>assert</code> macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function---the latter are respectively the values of the preprocessing macros <code>&#95;<em>FILE</em>&#95;</code> and <code>&#95;<em>LINE</em>&#95;</code> and of the identifier <code>&#95;<em>func</em>_)</code> on the standard error stream in an implementation-defined format. It then calls the <code>abort</code> function.</p></blockquote>Because {{assert()}} calls {{abort()}}, cleanup functions registered with {{atexit()}} are not called.  If the intention of the programmer is to properly clean up in the case of a failed assertion, then runtime assertions should be replaced with static assertions where possible (see [DCL03-C. Use a static assertion to test the value of a constant expression|DCL03-C. Use a static assertion to test the value of a constant expression]).  When the assertion is based on runtime data, the {{assert}} should be replaced with a runtime check that implements the adopted error strategy (see [ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy|ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy]).

The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function—the latter are respectively the values of the pre-processing macros _FILE_ and _LINE_ and of the identifier _func_) on the standard error stream in an implementation-defined format. It then calls the abort function.

Because assert() calls abort(), cleanup functions registered with atexit() are not called. If the intention of the programmer is to properly clean up in the case of a failed assertion, then runtime assertions should be replaced with static assertions where possible. (See recommendation DCL03-C. Use a static assertion to test the value of a constant expression.) When the assertion is based on runtime data, the assert should be replaced with a runtime check that implements the adopted error strategy. (See recommendation ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy.)

See recommendation See ERR04-C. Choose an appropriate termination strategy, for more information on program termination strategies and recommendation MSC11-C. Incorporate diagnostic tests using assertions, for more information on using the assert() macro.

...

This noncompliant code example defines a function that is called before the program exits to clean up.

Code Block
bgColor#ffcccc

void cleanup(void) {
  /* Delete temporary files, restore consistent state, etc. */
}

int main(void) {
  if (atexit(cleanup) != 0) {
    /* Handle error */
  }

  /* ... */

  assert(/* something bad didn't happen */);

  /* ... */
}

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

ERR06-C

medium

unlikely

medium

P4

L3

Automated Detection

Tool

Version

Checker

Description

Section

Compass/ROSE

 

 

Section

can detect some violations of this rule. However, it can only detect violations involving abort() because assert() is implemented as a macro

...

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Other Languages

Related Guidelines

CERT This rule appears in the C++ Secure Coding Standard as : ERR06-CPP. Understand the termination behavior of assert() and abort().

Bibliography

unmigrated-wiki-markup

\[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] Section 7.2.1.1, "The {{assert}} macro," and Section 7.20.4.1, "The {{abort}} function" \[[ISO/IEC PDTR 24772|AA. Bibliography#ISO

ISO/IEC PDTR 24772]\] "REU Termination Strategy"

Bibliography

...

      12. Error Handling (ERR)