Warning might be useful.
Warning might be useful.
> I don't expect compiler to care about it, just put function call into object code and move on.
memcpy actually has a few semantics that cannot be legally expressed in C (specifically, strict aliasing doesn't kick in). All modern compilers actually define memcpy as a compiler-builtin, and they rely on memcpy's semantics for optimization purposes.
Or, put more bluntly, memcpy does not correspond to a function call in object code. C is not a thin wrapper around assembly code, and has not been so for quite some time.
The actual test comes later: the real memcpy with three arguments, if it exists, is mislinked into the test executable; if memcpy cannot be found linking fails.
The test program would hopefully crash badly in case it is actually run, but the test is not about memcpy behaviour or about what the parameters of memcpy are.
memcpy is so magical that some specific undefined behavior is allowed. It's more than a mere library function- it's closer to a compiler intrinsic.
If you want to use a non-standard function that coincidentally happens to be memcpy, you have to use special compiler flags to inform the compiler that C library semantics are not in effect (e.g., -ffreestanding). Of course, the entire point of these checks is to figure out if the C library has these functions in the first place, so using these options during the tests would defeat the purpose.
> The actual test comes later: the real memcpy with three arguments, if it exists, is mislinked into the test executable; if memcpy cannot be found linking fails.
The actual test both compiles and links the executable, although it (obviously) doesn't attempt to run it. Whether it fails in the compile or the link step is immaterial to the test, as it fails either way.
Are you sure? I hear this a lot, but I don't think it's really true. char pointers are allowed to alias pointers to any other type in standard C (C17 6.5p7,) so unless I'm missing something, a correct C implementation of memcpy could just cast both its arguments to char pointers and copy them char-by-char.
I agree with your premise that the call to memcpy() is undefined, but I think that's entirely because of the conflicting definition, and has nothing to do with any special semantics of memcpy, so it would equally apply to any other standard library function.
I'm not completely certain. I have definitely seen this assertion before made by people more well-versed in the C standard than I, but I don't recall the exact argument. I think it may be the case that the write-via-char causes the effective type of memory to change (so it can only be read by char from that point on), but again, I don't trust my judgement here.
memmove on the other hand can't be implemented in standard C, but it can be implemented on most platforms using only implementation-defined behaviour, because casting a pointer to an intptr_t is implementation-defined, but on most platforms with a flat memory model, it gives you the linear memory address.
The compiler has special knowledge of memcpy and may introduce calls to it even if you don't call it anywhere in your code - see this : https://gcc.godbolt.org/z/_w78qd
The code above does not do so.
Contrary to what other people have suggested, according to my understanding of the C language standard, the word `memcpy` is not magical in any way, and undefined behaviour only comes in because the code will call `memcpy` with incorrect signature.
https://www.gnu.org/software/libc/manual/html_node/Reserved-...
I guess this is not an argument that the above code to check for memcpy() is illegal, per se, but it's at the very least totally superfluous.