Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is memcpy(&a + 1, &b + 1, 0) defined in C11?

This question follows this previous question about the definedness of memcpy(0, 0, 0), which has been conclusively determined to be undefined behavior.

As the linked question shows, the answer hinges on the contents of C11's clause 7.1.4:1

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, […]) […] the behavior is undefined. […]

The standard function memcpy() expects pointers to void and const void, as so:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n); 

The question is worth asking at at all only because there are two notions of “valid” pointers in the standard: there are the pointers that can validly be obtained through pointer arithmetics and can validly be compared with <, > to other pointers inside the same object. And there are pointers that are valid for dereferencing. The former class includes “one-past” pointers such as &a + 1 and &b + 1 in the following snippet, whereas the latter class does not include these as valid.

char a; const char b = '7'; memcpy(&a + 1, &b + 1, 0); 

Should the above snippet be considered defined behavior, in light of the fact that the arguments of memcpy() are typed as pointers to void anyway, so the question of their respective validities cannot be about dereferencing them. Or should &a + 1 and &b + 1 be considered “outside the address space of the program”?

This matters to me because I am in the process of formalizing the effects of standard C functions. I had written one pre-condition of memcpy() as requires \valid(s1+(0 .. n-1));,until it was pointed to my attention that GCC 4.9 had started to aggressively optimize such library function calls beyond what is expressed in the formula above (indeed). The formula \valid(s1+(0 .. n-1)) in this particular specification language is equivalent to true when n is 0, and does not capture the undefined behavior that GCC 4.9 relies on to optimize.

like image 520
Pascal Cuoq Avatar asked Aug 19 '14 18:08

Pascal Cuoq


People also ask

What C library is memcpy in?

memcpy() function in C/C++ The function memcpy() is used to copy a memory block from one location to another. One is source and another is destination pointed by the pointer. This is declared in “string. h” header file in C language.

What does memcpy function do in C++?

The memcpy() function in C++ copies specified bytes of data from the source to the destination. It is defined in the cstring header file.

When should memcpy be used?

In the C language memcpy() function is used to copy a block of memory from one location to another.

Is memcpy faster than loop?

memcpy is only faster if: BOTH buffers, src AND dst, are 4-byte aligned. if so, memcpy() can copy a 32bit word at a time (inside its own loop over the length)

What is memcpy in C++?

C C++ Server Side Programming. The function memcpy () is used to copy a memory block from one location to another. One is source and another is destination pointed by the pointer. This is declared in “string.h” header file in C language. It does not check overflow. Here is the syntax of memcpy () in C language,

What is the difference between memcpy () and SRC ()?

Following is the declaration for memcpy () function. dest − This is pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*. src − This is pointer to the source of data to be copied, type-casted to a pointer of type void*.

Is memcpy () safe?

According to " Please Join me in welcoming memcpy () to the SDL Rogues Gallery " memcpy is being banned as unsafe. It makes sense that gets (), strcpy and similar apis where the destination size is unclear. Is memmove () next? Show activity on this post. The point with all these “safe” methods is:

What is the declaration for memcpy () function?

Following is the declaration for memcpy () function. dest − This is pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.


1 Answers

C11 says:

(C11, 7.24.2.1p2) "The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1."

&a + 1 itself is a valid pointer to integer addition but &a + 1 is not a pointer to an object, so the call invokes undefined behavior.

like image 159
ouah Avatar answered Sep 18 '22 18:09

ouah