I have the following code:
uint8_t buffer[16];
uint8_t data[16];
uint8_t buffer_length = 16;
uint8_t data_length = 0;
memcpy(buffer + buffer_length, data, data_length);
memcpy should be a no-op, because data_length is zero. However buffer + buffer_length points just outside of the allocated memory. I wonder if it could trigger some kind of undefined behaviour? Should I wrap this memcpy with an additional if?
I understand that any reasonable implementation of memcpy would work fine, however this question is more from the code correctness perspective and avoiding undefined behaviours.
As the answer of Stephen C points out, the C17 specification is a bit vague about whether or not this is well-defined.
However, the C23 specification clarifies this in a footnote to the part of 7.1.4 stating
If a function argument is described as being an array, the pointer passed to the function shall have a value such that all address computations and accesses to objects (that would be valid if the pointer did point to the first element of such an array) are valid.
The footnote (235) reads:
This includes, for example, passing a valid pointer that points one-past-the-end of an array along with a size of 0, or using any valid pointer with a size of 0.
The first part of the sentence explicitly defines the OP case as well-defined.
Adding this statement can be seen as admitting that the C17 specification is not sufficiently clear on this point and thus, it cannot be ruled out that an implementer of a C17 compiler may in good faith interpret the standard such that this case is not defined behavior.
However, C23 should remove that uncertainty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With