# V2652. MISRA. Argument of an integer constant macro should have an appropriate form.

This diagnostic rule is based on the MISRA (Motor Industry Software Reliability Association) software development guidelines.

This diagnostic rule is relevant only for C.

According to the C11 standard (Section 7.20.4), macro arguments for integer constants should meet the following requirements:

- They should be non-negative integer constants in decimal, octal, or hexadecimal notation.
- They should not contain suffixes, since the type and dimension are defined by the macro itself.
- Values should be within the valid range for the type corresponding to the width specified in the macro name. For example, the `INT8_C` value should be in the `[-128 .. 127]` range.

Note. The argument should be an integer literal. It excludes any other expressions, even with a unary minus.

In addition, incorrect use of integer constant macros can lead to unexpected behavior.

The example:

    void do_something_ui(unsigned int value);
    void do_something_ul(unsigned long value);
    void do_something(unsigned long long);

    #define DO_SOMETHING(X) Generic( (X)                             \
                                    , unsigned int: do_something_ui  \
                                    , unsigned long: do_something_ul \
                                    , default: do_something ) (X)

    int foo(void)
    {
      DO_SOMETHING(UINT32_C(16L));
    }

During the code compilation, the preprocessor converts the `UINT32_C(16L)` macro call into a numeric `16LU` literal of the `unsigned long` type. As a result, the generic selection expression chooses the `unsigned long` association, and the `do_something_ul` function is called. This behavior may be unexpected, as the intended result of the macro call is a literal of the `unsigned int` type, and the function `do_something_ui` is called.

The fixed code:

    void do_something_ui(unsigned int value);
    void do_something_ul(unsigned long value);
    void do_something(unsigned long long);

    #define DO_SOMETHING(X) Generic( (X)                             \
                                    , unsigned int: do_something_ui  \
                                    , unsigned long: do_something_ul \
                                    , default: do_something ) (X)

    int foo(void)
    {
      DO_SOMETHING(UINT32_C(16));
    }

This diagnostic is classified as:

MISRA-C-2023-7.5