Search code examples
clanguage-lawyerc-stringsstrncmp

Is it undefined behavior what strncmp(s1, s2, 0) returns (i.e. the last argument is zero)?


It is not immediately clear from the standard what strncmp (from string.h)

int strncmp(const char *s1, const char *s2, size_t n);

should return if its 3rd argument n is 0.

According to the C17 standard draft, 7.24.4.4:

The strncmp function compares not more than n characters (characters that follow a null character are not compared) [...].

The strncmp function returns an integer greater than, equal to, or less than zero, accordingly as the [...] array pointed to by s1 is greater than, equal to, or less than the [...] array pointed to by s2.

What should strncmp(s1, s2, 0) return? Or is the standard silent on the case of strncmp's last argument being 0?

My intuition tells me that 0 as the return value would make the most sense:

  • 0 is the most "symmetric" answer (a negative or positive return value implies an asymmetry and is inconsistent with no comparisons having been undertaken).
  • 0 is consistent with a model where 0 is assumed until a difference has been found, n comparisons have been undertaken, or the end of the strings has been reached.

But the above reasoning is philosophical.

It seems that the standard doesn't technically proclaim anything about this case. I think it would be better if it

  • explicitly defined a result (such as 0) or
  • outlawed it.

For what it's worth, glibc gives me 0 (and no warnings or errors) for a bunch of simple test cases such as strncmp("abc", "def", 0) with the following compiler flags:

-Wall -Wextra -std=c90 -pedantic
-Wall -Wextra -std=c17 -pedantic

Solution

  • From the C11 Standard (7.23.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.

    The same is written in the following C Standards including the C23 Standard.

    It is logically consistent. The parameter n specifies the size of a range. When n is equal to 0 then that means that the range is empty. And two empty sets can not be greater or less each other. They are both empty sets and hence are equal each other.