One section claims "Physical Subtyping is Broken", where "physical subtyping" is defined as "the struct-based implementation of inheritance in C." I assume this means the typical pattern of:
typedef struct {
int base_member_1;
int base_member_2;
} Base;
typedef struct {
Base base;
int derived_member 1;
} Derived;
The article claims physical subtyping is broken because casting between pointer types results in undefined behavior. The article gives this example: #include <stdio.h>
typedef struct { int i1; } s1;
typedef struct { int i2; } s2;
void f(s1 *s1p, s2 *s2p) {
s1p->i1 = 2;
s2p->i2 = 3;
printf("%i\n", s1p->i1);
}
int main() {
s1 s = {.i1 = 1};
f(&s, (s2 *)&s);
}
I agree this example is broken, but casting between pointer types in this way is totally unnecessary for C-based inheritance. You can do upcasts and downcasts that are totally legal: Derived d;
// Legal upcast:
Base* base = &d->base;
// Legal downcast:
Derived* derived = (Derived*)base;
So I don't think the article has proved that "Physical Subtyping is Broken."The next section says that "Chunking Optimizations Are Broken," because code like this is illegal:
void copy_8_bytes(char *dst, const char *src) {
*(uint64_t*)dst = *(uint64_t*)src;
}
While this is true, such optimizations are generally unnecessary. For example, write this instead as: void copy_8_bytes(char *dst, const char *src) {
memcpy(dst, src, 8);
}
If you compile this on an architecture like x86 that truly allows unaligned reads, you'll see that modern compilers do the "chunking optimization" for you: 0000000000000000 <copy_8_bytes>:
0: 48 8b 06 mov rax,QWORD PTR [rsi]
3: 48 89 07 mov QWORD PTR [rdi],rax
6: c3 ret
It says next that "int8_t and uint8_t Are Not Necessarily Character Types." That is indeed a good point and probably not well-known. So I agree this is something people should keep in mind. But most of this article is warning against practices that are generally unnecessary and known to be bad C in 2016.It's true that a lot of legacy code-bases still break these rules. But many are cleaning up their act, fixing practices that were never correct but used to work. For example, here is an example of Python fixing its API to comply with strict aliasing, and this is from almost 10 years ago: https://www.python.org/dev/peps/pep-3123/