3 ms·
> C is just some readable assembly. Here's one article that argues the other side. I like this part a lot, though the wording is a maybe a little bit argumenta
by oconnor663 9y ago
> C is just some readable assembly.
Here's one article that argues the other side. I like this part a lot, though the wording is a maybe a little bit argumentative :)
"Be knowledgeable about what’s actually in the C and C++ standards since these are what compiler writers are going by. Avoid repeating tired maxims like “C is a portable assembly language” and “trust the programmer.” Unfortunately, C and C++ are mostly taught the old way, as if programming in them isn’t like walking in a minefield. Nor have the books about C and C++ caught up with the current reality. These things must change."
https://blog.regehr.org/archives/1520 https://blog.regehr.org/archives/1520
- jokoon 9y agoI said it's readable, but it's just some simple translation. C still has all the issues of having to write assembly, so a C programmer should have to check if its C code is not doing anything unsafe, like an ASM developer would. Programming is not easy, and it always has been a minefield. You cannot write good code quickly. Even learning rust will have a cost, although it's a worthy cost. Writing unsafe code is cheap and was often a good enough solution.
- oconnor663 9y ago> it's just some simple translation 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 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.