The memcpy()
function is perfectly fine. The C11 bounds checking functions were introduced as part of reducing the chance of buffer overflow defects.
Document N1967, Field Experience With Annex K — Bounds Checking Interfaces, in the section Unnecessary Uses has this to say:
A widespread fallacy originated by Microsoft's deprecation of the
standard functions [DEPR] in an effort to increase the adoption of the
APIs is that every call to the standard functions is necessarily
unsafe and should be replaced by one to the "safer" API. As a result,
security-minded teams sometimes naively embark on months-long projects
rewriting their working code and dutifully replacing all instances of
the "deprecated" functions with the corresponding APIs. This not only
leads to unnecessary churn and raises the risk of injecting new bugs
into correct code, it also makes the rewritten code less efficient.
The sizeof
operator is a compile time operator which means that the size calculation is done by what ever information is available to the compiler at the time of compilation. This is why using the operator can be problematic and a source of runtime errors when used with pointers and arrays. Increasing the warning level of the compiler and using a static code analysis tool can help find these problem areas.
Because the sizeof
operator is a compile time operator, there isn't a much you can do for a compiler error or warning though your particular compiler may have a warning level you can set that will do this type of check.
What I have done is to have a Preprocessor macro that I can use for a run time check in debug builds or special release builds used in verification that will be removed when doing a release build for production in order to remove the checking overhead.
So if you have source such as:
uint8_t mybuffer[4];
float f;
memcpy(&f, mybuffer, sizeof(mybuffer));
that will be have the correct number of bytes because the array mybuffer[4]
along with its actual size is available to the compiler.
However I would actually prefer the following modification by specifying the size of the target for the memcpy()
instead. This ensures that there will not be a buffer overflow even if the source size is incorrect.
uint8_t mybuffer[4];
float f;
memcpy(&f, mybuffer, sizeof(f));
where problems with the sizeof
operator develop is when the compiler is unable to deduce the size of the array or the size of the object whose address is in a pointer. Using it with array declarations of function arguments isn't safe either.
If you have a function int xxx (int a[5])
and in that function you try using the sizeof
operator to get the array size in bytes, what you will probably get is the size of an int *
instead.