# V2648. MISRA. Null pointer constant must be derived by expansion of the NULL macro provided by the implementation.

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

This diagnostic rule is relevant only for C.

A null pointer constant must be derived via the expansion of the `NULL` macro provided in the standard library implementation. This requirement applies in the following cases:

- The constant is assigned to the pointer.
- The constant is one of the operands of the `!=` or `==` operator, where the other operand is the pointer.
- The constant is the second operand of the conditional operator (`?:`), where the third operand is the pointer.
- The constant is the third operand of the conditional operator (`?:`), where the second operand is the pointer.

Using the `NULL` macro instead of the `0` constant makes the code more readable and clearly separates pointer semantics from numeric values, that reduces ambiguity.

Note. The null pointer constant can be written as `(void*)0`, even if it is not the result of expanding the `NULL` macro.

The example of erroneous code:

    // Declaring structure in another file
    struct Device {
        void* config;
        int status;
    };

    int updateDevice(struct Device* dev, int newStatus) {
    // ....
    // Here is a large fragment of code...
    // ....
        if (dev == 0) {                  // <=
            return 0;
        }

        if (newStatus == STATUS_RESET) {
            dev->config = 0;             // <=
            dev->status = newStatus;
            return 1;
        }
        return 0;
    }

In the example, the `0` constant is used instead of `NULL`, which may lead developers to think that values are handled rather than pointers. To avoid ambiguity in the interpretation of the `dev == 0` and `dev->config = 0` expressions, it would be recommended to replace `0` with `NULL` or `(void *)0`.

The fixed code:

    #include <stddef.h>
    int updateDevice(struct Device* dev, int newStatus) {
    // ....
    // Here is a large fragment of code...
    // ....

        if (dev == NULL) {              // ok
            return 0;
        }

        if (newStatus == STATUS_RESET) {
            dev->config = NULL;         // ok
            dev->status = newStatus;
            return 1;
        }
        return 0;
    }

Exception. The `{0}` initializer can be used to initialize an aggregate type object or a union with pointers.

The fixed code:

    typedef struct EXAMPLE_STRUCT
    {
      void* ptr;
    } tExStruct;

    tExStruct ya = { 0 };   // ok

This diagnostic is classified as:

MISRA-C-2023-11.9