Question

In particular, is the following well-defined, or does it exhibit undefined behavior?

memcmp(0, 0, 0);

Does this differ between C and C++? Ideally, please provide a quote from the standard(s).

Était-ce utile?

La solution 2

In particular, is the following well-defined, or does it exhibit undefined behavior?

It's undefined. C99 7.21.1/2 says about all the string functions:

Unless explicitly stated otherwise in the description of a particular function in this subclause, pointer arguments on such a call shall still have valid values

and the description of memcmp in 7.21.4.1 doesn't explicitly state otherwise.

Does this differ between C and C++?

No, C++ defers to C for its definition of the C library functions, and doesn't have anything special to say about memcmp.

Autres conseils

It is amazing that although this appears to be a case of an obvious bug in the standard - which neglects to say that zero-length memcmp is fine (and always returns 0) - mountains of theory was built to explain why this should be labeled "undefined behavior". The above accepted answer is a good example, and so is the later discussion here.

Sadly, after the theory that memcmp(0,0,0) is undefined took hold, Gcc decided to strongly enforce this unfortunate decision, by adding a __nonull attribute to memcmp, causing possibly-wrong optimizations and UBSAN warnings. Only at that point, did this call really become undefined :-(

But if we were to look at it logically, memcmp(0, 0, 0) is well-defined, and should always returns 0 (equality): The functionality of memcmp() is described in Posix as:

The memcmp() function shall compare the first n bytes (each interpreted as unsigned char) of the object pointed to by s1 to the first n bytes of the object pointed to by s2.

When n=0, this means no bytes will be compared. If no bytes are compared, no pointer should ever be dereferenced, and it doesn't matter what this pointer is. That should be obvious, and the fact that the C standard forgot to mention it is nothing more than a bug in the standard.

Interestingly, the Linux memcmp(3) and the FreeBSD memcmp(3) manual pages, disagree with gcc, and claim that this case should be allowed:

The Linux manual page says:

If n is zero, the return value is zero.

While the BSD one says:

Zero-length strings are always identical.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top