Q: Why is memcpy safer than pointer casting for type punning?
💡 Concept in a Nutshell
memcpy is the "Official Copy Machine" of C: It doesn't care if your data is a math book or a cookbook; it only sees "paper" (Bytes) and duplicates them from point A to point B without violating language laws.
1. Life Analogy (The Librarian vs. The Xerox)
Imagine you have a Math Book but you want to read it as a Cookbook.
-
Pointer Casting (
*(int*)&f): This is like forcing a Librarian to read a Math book as a Cookbook. The Librarian will get confused because it violates the "Library Classification Rules" (Strict Aliasing). -
memcpy: This is like putting the Math book into a Xerox machine. The machine doesn't read the words; it just copies the ink onto new paper. Now you have "Cookbook-shaped" paper with "Math-ink" on it. It’s perfectly legal because the Xerox machine is allowed to touch any paper!
2. Code Example
#include <stdio.h>
#include <string.h>
int main() {
float f = 3.14f;
int i;
// "Photocopy" the 4 bytes of f into i
memcpy(&i, &f, sizeof(int));
printf("Memory content of float 3.14f = 0x%X\n", i);
// Output: 0x4048F5C3 (on IEEE 754 systems)
// It works backwards too!
int j = 1078523331;
float g;
memcpy(&g, &j, sizeof(float));
printf("Int 1078523331 as float = %f\n", g);
// Output: 3.140000
return 0;
}
3. Standard (C99 Clause): 6.5.7
The char* Exception: The C standard allows char* (and unsigned char*) to alias any object type. Since memcpy is defined to operate byte-by-byte, it bypasses the Strict Aliasing Rule.
4. Key Techniques (Why it Works)
-
memcpy: The most robust way to copy bits between types. -
Compiler Optimization: Modern compilers (GCC/Clang) recognize
memcpyfor type punning. On Arm64 or x86_64, they often optimize it into a single register move (ldr/strormov), meaning zero function call overhead.
5. Warning & Pro-Tips
-
The Overlap Trap:
memcpyassumes the source and destination do NOT overlap. If they might, always usememmove. -
Size Matters: Ensure
sizeof(dest) >= sizeof(src)to avoid buffer overflows. -
Compiler Flag: In large projects (like the Linux Kernel), you might see
-fno-strict-aliasingused to relax these rules globally.
Top comments (0)