Main Content

MISRA C:2012 Rule 21.16

The pointer arguments to the Standard Library function memcmp shall point to either a pointer type, an essentially signed type, an essentially unsigned type, an essentially Boolean type or an essentially enum type

Description

Rule Definition

The pointer arguments to the Standard Library function memcmp shall point to either a pointer type, an essentially signed type, an essentially unsigned type, an essentially Boolean type or an essentially enum type.

This rule comes from MISRA C™: 2012 Amendment 1.

Rationale

The Standard Library function

memcmp ( lhs, rhs, num );
performs a byte-by-byte comparison of the first num bytes of the two objects that lhs and rhs point to.

Do not use memcmp for a byte-by-byte comparison of the following.

TypeRationale
Structures If members of a structure have different data types, your compiler introduces additional padding for data alignment in memory. The content of these extra padding bytes is meaningless. If you perform a byte-by-byte comparison of structures with memcmp, you compare even the meaningless data stored in the padding. You might reach the false conclusion that two data structures are not equal, even if their corresponding members have the same value.
Objects with essentially real floating type and essentially complex floating typeThe same floating point value can be stored using different representations. If you perform a byte-by-byte comparison of two variables with memcmp, you can reach the false conclusion that the variables are unequal even when they have the same value. The reason is that the values are stored using two different representations.
Essentially char arraysEssentially char arrays are typically used to store strings. In strings, the content in bytes after the null terminator is meaningless. If you perform a byte-by-byte comparison of two strings with memcmp, you might reach the false conclusion that two strings are not equal, even if the bytes before the null terminator store the same value.

Troubleshooting

If you expect a rule violation but do not see it, refer to Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <stdbool.h>
#include <stdint.h>

struct S {
//...
};

bool f1(struct S* s1, struct S* s2)
{
    return (memcmp(s1, s2, sizeof(struct S)) != 0); /* Non-compliant */
}

union U {
    uint32_t range;
    uint32_t height;
};
bool f2(union U* u1, union U* u2)
{
    return (memcmp(u1, u2, sizeof(union U)) != 0); /* Non-compliant */
}

const char a[ 6 ] = "task";
bool f3(const char b[ 6 ])
{
    return (memcmp(a, b, 6) != 0); /* Non-compliant */
}

In this example:

  • Structures s1 and s2 are compared in the bool_t f1 function. The return value of this function might indicate that s1 and s2 are different due to padding. This comparison is noncompliant.

  • Unions u1 and u2 are compared in the bool_t f2 function. The return value of this function might indicate that u1 and u2 are the same due to unintentional comparison of u1.range and u2.height, or u1.height and u2.range. This comparison is noncompliant.

  • Essentially char arrays a and b are compared in the bool_t f3 function. The return value of this function might incorrectly indicate that the strings are different because the length of a (four) is less than the number of bytes compared (six). This comparison is noncompliant.

Check Information

Group: Standard libraries
Category: Required
AGC Category: Required

Version History

Introduced in R2017a