9

In reading: How can I check that elements of an array are all same without using counter? , @Skizz uses the nifty solution:

memcmp (&string [0], &string [1], sizeof string [0] * (N - 1))

So if N happens to be 1, we get

memcmp (&string [0], &string [1], 0)

Is the return value certain to be 0 when the compare length is 0?


Test case (Cygwin gcc version 4.8.1 windows 64-bit) returns 0. So I know on this and a few other compilers/platforms that it is 0.

printf("%d\n", memcmp("foo", "bar", 0));

C11 draft spec follows, but appears quiet on the issue. Maybe another part of the spec or something says something?

7.24.4.1 The memcmp function
Synopsis

#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);

Description
The memcmp function compares the first n characters of the object pointed to by s1 to the first n characters of the object pointed to by s2.

Returns
The memcmp function returns an integer greater than, equal to, or less than zero, accordingly as the object pointed to by s1 is greater than, equal to, or less than the object pointed to by s2.


(Assume &string [1] did not reference illegal memory)

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • If 1==N then don't do it. – Mike Makuch Sep 26 '13 at 17:44
  • `memcmp` is not reliable for comparing two objects for the same value if the objects may contain padding bytes, padding bits, or multiple encodings of the same value (such as a positive zero and a negative zero). – Eric Postpischil Sep 26 '13 at 17:56
  • You're basically wanting to call a function (memcmp) but telling it (zero length) not to perform it's task! If you don't want a function to execute, in general you shouldn't call it. :-) – Mike Makuch Sep 26 '13 at 19:16
  • 4
    @koodawg: Quite the opposite, in virtually all cases a function that has well-defined behavior in "no op" situations allows for significantly cleaner code. One of the most well-known examples is `free` with null pointer as an argument. It is always cleaner to just do `free(p)` instead of `if (p) free(p)`. The same applies to `memcmp`. – AnT stands with Russia Sep 26 '13 at 19:35

1 Answers1

14

The relevant part of the specification is really this one

7.21 String handling

7.21.1 String function conventions

2 Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function. 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, as described in 7.1.4. On such a call, a function that locates a character finds no occurrence, a function that compares two character sequences returns zero, and a function that copies characters copies zero characters.

That means that memcmp is guaranteed to return zero when the supplied sequence length is zero.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Looks good to me. Same in _C11 draft 7.24.1 2_. I suppose your reference is from C99? – chux - Reinstate Monica Sep 26 '13 at 18:41
  • 1
    Are we sure that memcmp falls into 7.21 String handling? It's not technically a string function, obviously. – Mike Makuch Sep 26 '13 at 19:19
  • 2
    @koodawg: Yes, we are. It is not really about "string functions", but rather about functions described in "this subclause" (7.21). And `mem...` functions are indeed described in this subclause. Moreover, the fact that `mem...` functions are described under 7.21 formally makes them "string functions". – AnT stands with Russia Sep 26 '13 at 19:32
  • 2
    Also 7.24 (in C11) describes the string handling functions in question as those which are "useful for manipulating arrays of character type *and other objects treated as arrays of character type*" (emphasis mine). All the `mem...` functions are described in terms of "copies `n` characters", "compares the first `n` characters" and the like, since "bytes" and `char`s are pretty much the same thing in C. – Crowman Sep 26 '13 at 20:34