2

I just tested the following on my setup (gcc 4.8.2, recent uClibc), and it runs fine:

#include <string.h>
int main(int argc, char **argv) {
    char buf[4], fub[4] = "abc";
    memmove(buf, fub, 0);
    memmove(buf, NULL, 0);
    memmove(NULL, fub, 0);
    memmove(NULL, NULL, 0);
    return 0;
}

It also works with memcpy. So it's clear that passing NULLs to these functions works OK in practice, on at least some setups. But I want to code defensively, and am trying to determine whether any C standard permits me to rely on this behavior, or whether it's undefined or implementation-defined.

This answer points out that the C99 standard does specify that passing a size of 0 to these functions shall be valid. Here is the text, from section 7.21.1:

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.

Reading section 7.1.4, on the other hand, seems to say that passing NULLs is not defined:

Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined.

Is that your understanding too? Can anyone confirm/deny whether the standard leaves this behavior undefined?

I'm mainly targeting C99, but feedback about other C standards is also welcome.

Community
  • 1
  • 1
dubiousjim
  • 4,722
  • 1
  • 36
  • 34
  • Note that it says that a *"function that copies characters copies zero characters"*. It doesn't specify what shall be done with the pointers: i.e. they may still be evaluated. If you're doing defensive programming then checking for NULL is the best way to go. – Kninnug Mar 07 '14 at 22:40
  • Thanks @Urit, I didn't find that. – dubiousjim Mar 07 '14 at 22:41
  • 2
    Section 7.21.1 is pretty clear: **pointer arguments on such a call shall still have valid values**. That's all you need to know. `NULL` is not a valid value for a pointer, thus it is not safe to pass it. Voting to close as a duplicate, like @Urit mentioned. – Filipe Gonçalves Mar 07 '14 at 22:49
  • 1
    Thanks all. This is also what the standard seemed to me to say. I just wanted to see if there was something I was missing that others knew about. – dubiousjim Mar 07 '14 at 22:51

0 Answers0