I think this is the part that the article is arguing against. For sure, I agree that many of the common problems we run into with C code (out-of-bounds reads, uses-after-free, etc.) are the result of the compiler doing "exactly what you told it to do." But there are also new problems that come up as a result of aggressive C compiler optimizations, which are _not_ what would happen in a simple translation:
- Strict aliasing violations. If two pointers point to different types, the compiler is allowed to assume that the memory they point to doesn't overlap. It can reorder a write and a read based on this rule, even when they should be causally related within a single thread.
- Non-obvious undefined behavior. For example, https://www.imperialviolet.org/2016/06/26/nonnull.html. The C standard says that passing a null pointer to memcpy is undefined, even if the size argument is zero. If you pass a pointer to memcpy (assuming a size of zero would make that a no-op) and then check it for null, the compiler will completely skip that check.
These are cases where modern compilers do something very different from what a human assembly programmer would intuitively do. It's not the majority of code in any program that has to worry about this, but I think the majority of programs do have to worry about this somewhere.
I think this is the part that the article is arguing against. For sure, I agree that many of the common problems we run into with C code (out-of-bounds reads, uses-after-free, etc.) are the result of the compiler doing "exactly what you told it to do." But there are also new problems that come up as a result of aggressive C compiler optimizations, which are _not_ what would happen in a simple translation:
- Strict aliasing violations. If two pointers point to different types, the compiler is allowed to assume that the memory they point to doesn't overlap. It can reorder a write and a read based on this rule, even when they should be causally related within a single thread.
- Non-obvious undefined behavior. For example, https://www.imperialviolet.org/2016/06/26/nonnull.html. The C standard says that passing a null pointer to memcpy is undefined, even if the size argument is zero. If you pass a pointer to memcpy (assuming a size of zero would make that a no-op) and then check it for null, the compiler will completely skip that check.
These are cases where modern compilers do something very different from what a human assembly programmer would intuitively do. It's not the majority of code in any program that has to worry about this, but I think the majority of programs do have to worry about this somewhere.