﻿# 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](https://misra.org.uk/) \(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`](https://en.cppreference.com/w/c/types/NULL.html) 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](https://en.cppreference.com/w/cpp/language/operator_other.html#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:

```cpp
// 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:

```cpp
#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:

```cpp
typedef struct EXAMPLE_STRUCT
{
  void* ptr;
} tExStruct;

tExStruct ya = { 0 };   // ok
```