8 ms·
The evidence is on the side of the parent poster. Incredibly experienced programmers write C without those tools, and with practically no exceptions memory iss
by TheDong 9y ago
The evidence is on the side of the parent poster.
Incredibly experienced programmers write C without those tools, and with practically no exceptions memory issues, crashes, and vulnerabilities surface if the code is large enough and the project used enough.
An easy example of this is the Linux kernel. They historically had relatively few verification tools and have one of the largest C codebases out there.
There's a new vulnerability related to memory safety every two or three weeks.
There's a bug fixed due to C memory management at least daily.
None of those bugs would have happened in Rust. Most of them couldn't have happened in well written C++ (whereas this well-written C is chock full of them).
Note as well that the kernel now gets some of the most exhaustive verification of any project (such as from google's syzkaller, etc), and it still has tons of C memory issues.
- bsenftner 9y ago"Incredibly experienced programmers" ? The language is simple and well defined to the degree one can map out exactly what happens on paper, if need be. Everyone is so brainwashed to think C is some low level assembly like language that is "hard". No, not at all. It simply provides no training wheels or safety harness - meaning one needs to know what they are doing, not coding in a "type and see what it does" style.
- TheDong 9y ago> It simply provides no training wheels or safety harness - meaning one needs to know what they are doing Meaning that if you are human you will make mistakes. My point is that people who do know what they're doing still make mistakes. Clearly the tool does not match the reality of human cognition.
- geezerjay 9y ago> Meaning that if you are human you will make mistakes. You can make mistakes in any language, and they will bite you in the backside any way. Just because some people prefer to live in padded rooms that doesn't mean they can't or won't get hurt if they decide to pull stunts. Padded rooms just provide them with a false notion of safety that ends up making matters worse.
- deleted 9y ago[deleted]
- TheDong 9y ago> You can make mistakes in any language, and they will bite you in the backside any way. This is a false equivalency.. It's akin to saying "you can hit your thumb putting in a nail with any tool, so you might as well use a rock not a hammer since they're both bad". Yes, you can make mistakes in any language, but that's not a reason to ignore modern tooling and advances and continue. Other languages allow us to build abstractions and solve mistakes in ways which are just impossible with C... and without those abstractions, it's just needlessly difficult to keep all the state in your head and write correct code. An easy example of this is locking and ownership. In C, mutexes are managed manually and what they hold is by convention. It's easy to write races or accidentally deadlock (again as evidenced by such a bug in the kernel existing every few weeks). In languages with RAII, python's "with", etc, you can't forget to unlock the lock. It's one less thing to think about. In languages like rust, it's possible to model in the type system that a given resource can only be accessed while a mutex is locked. Again, one less way to make a mistake. C has no ability to provide or build abstractions that are this robust. Using C is, more often than not, like using a rock to hammer in a nail. > Just because some people prefer to live in padded rooms With C, people are living in a room where the floor is lava and nails coat most surfaces. I'll take my room that's carpeted, and if I need to pull a stunt and rip up the carpet, sure, I can do that, but at least I can walk normally most of the time.
- amag 9y ago> It's one less thing to think about. I've been a professional C++ programmer for almost two decades (and a C++ amateur for almost a decade before that). I've written large amounts of fairly advanced C++ using the latest standards. My current job however, is all plain C. One of the interesting (and, for a C++ fan like me, disturbing) things I've found is that the cognitive load is much lower when writing plain well-structured C. Sure, you need to remember to release that lock and free that memory but this you can do in a very structured way. What you win over C++ is that you don't need to view each line of code with suspicion ("What happens if this line throws an exception?", "I wonder what this line will cost in terms of performance?", "Could this operation cause a cascading destruction of objects I'm going to access further down?"). I love RAII, yet I've debugged enough crashes where "seemingly innocuous operation destructs some local object that has an owning reference to an object that shouldn't be destructed just yet and BAM!", that I'm beginning to doubt its usefulness outside of an exception-generating language (in C++ it's essential for proper exception-handling).
- bunderbunder 9y ago"type and see what it does" is a strawman. Some people absolutely do program this way, I don't deny that, but there's a huge gulf between that and the levels of verification it takes to ensure that a large program really does behave as intended. Typos, minor oversights, unforeseen consequences of refactoring. . . the number of things you need to guard against is immense, and nobody can be operating at 100% 100% of the time.
- liuliu 9y agoAnd very few people can know 100% 100% times. We build software on top of abstractions. Abstraction leaks, abstraction breaks and abstraction isolates you from "know what you are doing". If you build software in C, you will build abstractions in C, and debugging / analysis tools help to understand these abstractions.
- kccqzy 9y ago> The language is simple and well defined to the degree one can map out exactly what happens on paper, if need be. Without a copy of the language standard, I still can't remember all the intricate details about just arithmetic and comparison operators. Take the simple bitshift operators. What happens when the second operand is negative or larger than sizeof(left)*CHAR_BITS? What if it's equal? And the >> and << operators are not even symmetric in their definitions: left-shifting a negative value is undefined but right-shifting a negative value is implementation-defined! And even for simpler operators like + or >, can you immediately tell me all the integer promotion rules and usual arithmetic conversion rules? What happens when you add two integers with different signedness and width? I can't and I doubt most programmers can. Try implementing a special C interpreter where every undefined and implementation-defined behavior is configurable and you will see how complicated things are.
- jstimpfle 9y ago> What happens when the second operand is negative or larger than sizeof(left) * CHAR_BITS? What if it's equal? And the >> and << operators are not even symmetric in their definitions: left-shifting a negative value is undefined but right-shifting a negative value is implementation-defined! As a lover of C, these questions are totally irrelevant to me. What I've taken away is don't do things that do not have intuitively clear semantics. Use bitwise and shift operators only on unsigned numbers. Simple as that. And really I haven't found a need to do anything else. I think many of these complex rules are historical accidents or come from supporting a peculiar architecture or kind of hardware that's no longer relevant. In any case, remembering all these pesky rules is not C. C is simple. Remember how to stay away from the dubious operations and you're fine.
- aidenn0 9y agouint32_t foo(uint8_t ubyte) { return ubyte << 24; } Look ma, undefined behavior due to signed integer overflow (on 32 bit targets anyways), despite only unsigned types being declared. And what about the aliasing rules: char *start, *end; //This is a function that sets start/end to the start and end of an address range. It takes uintptr_t * arguments GetAddressRange((uintptr_t *)&start, (uintptr_t *)&end); *start=3; //Undefined behavior because we have now accessed start as both a uintptr_t and a char *.
- gowld 9y agoI'm glad that you are a video game programmer and you don't work on software where correctness matters.
- mbrodersen 9y agoYou clearly don't understand the world of video game programmers. I worked on a game (Banjo Kazooie) that ended up being turned into more than 6 million ROM cartridges and distributed worldwide through retail. The cost of producing the cartridges alone was millions of $. With no internet patching available in case of a bug. We took verification VERY seriously.