Main Content

MISRA C++:2023 Rule 22.3.1

The assert macro shall not be used with a constant-expression

Since R2024b

Description

Rule Definition

The assert macro shall not be used with a constant-expression.

Rationale

The assert macro is meant for checking conditions that can be evaluated only at run time. To check the value of an expression that is evaluated at compile time, use the static_assert macro instead.

The use of the assert macro with constant expressions can be problematic for these reasons:

  • If the assert expression fails, the failure is shown only at run time. With compile-time constants, you might want a failure to be reported at compilation time.

  • The assert macro can be disabled by using the NDEBUG flag or by other means. If the macro is disabled, your code bypasses checks using the assert macro and might show unexpected behavior.

Polyspace Implementation

The rule checker reports a violation on an assert macro if the macro argument is a compile-time constant. Following the MISRA™ C++:2023 specifications, the checker allows an exception for these cases:

  • If the argument is the literal value false.

  • If the argument is the literal value false coupled to a string literal with the && operator.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <cassert>

void Constant_assertions(int i) {
    assert(42);                                   // Noncompliant
    assert(3.1415927);                            // Noncompliant

    assert(sizeof(i) == 4);                       // Noncompliant
    assert(sizeof(int) == 4);                     // Noncompliant

    assert((sizeof(int) == 4) && "Bad int size"); // Noncompliant

    assert(true);                                 // Noncompliant
    assert(true && "message");                    // Noncompliant
    assert(true && (sizeof(int) < 4));            // Noncompliant

    assert(false || "message");                   // Noncompliant
    assert(false && (sizeof(int) > 4));           // Noncompliant

    assert("A string" && false);                  // Noncompliant

    assert(0);                                    // Noncompliant
    assert(0 && "message");                       // Noncompliant
    assert("Stop here");                          // Noncompliant

    char* msg = "message";
    assert(false && msg);                         // Noncompliant

    const int cst = 42;
    assert(cst == 42);                            // Noncompliant

    constexpr int c = 42;
    assert(c == 42);                              // Noncompliant
    assert((c == 42));                            // Noncompliant

    const char* const MSG = "message";
    assert(false && MSG);                         // Noncompliant 
}


static_assert( ( sizeof( char ) == 1 ), "Unknown target" );    // Compliant

int Nonconstant_assertions(int i) {
    assert(i != 100);                       // Compliant
    assert(Compliant(i+1));                 // Compliant 

    if ( i < 50 ) {
        assert(false);                      // Compliant by exception
    }

    if ( i == 50 ) {
        assert(false && "i == 50");         // Compliant by exception
    } 

    int* p = &i;
    assert(p);                              // Compliant

    int(*f)(int) = &Compliant;
    assert(f);                              // Compliant

    return i;
}

In this example, the function Constant_assertions() shows various examples of assert usage that violates the rule. In all the examples, the assert argument is an expression that is evaluated at compile time.

The function Nonconstant_assertions() shows uses of the assert macro that do not violate the rule because of one of these reasons:

  • The assert argument cannot be evaluated at compile time.

  • The assert argument is the literal value false, or false && "text" where text is a string literal.

Check Information

Group: Diagnostics library
Category: Required

Version History

Introduced in R2024b