Hacker News new | ask | show | jobs
by sqeaky 3496 days ago
I think that you have the formulation backwards. You claim that people can just write better, and should attain perfection.

> I don't think anyone can demonstrate that it is virtually impossible to write 100% safe C code.

I think most people come at the other way. Most people are aware that they are fallible and wants tools to help with that. Most people strive for perfection and none will ever actually attain it.

> I don't think anyone can demonstrate that it is virtually impossible to discover errors safely in C code.

There is a huge difference simply moving from C to C++ with exceptions. The type system in C++ can detect several classes of errors at compile time and prevent then grom going into the results.

Then for runtime problems if an underlying functions throws, it cannot simply be ignored. Any programmer can miss a single statement, or worse refactor a function with a void return to one that returns and error code (which then results in every caller ignoring the return value). However, it takes a special kind of malice to use something like carelessly catch(...) in C++ to disregard exceptions so that runtime errors are avoided. C++ with exceptions has more sane defaults because it fails fast and the failing itself doesn't need tests until it starts doing something meaningful.

Now imagine the advances in error detection moving to languages that catch additional classes of errors.

2 comments

> which then results in every caller ignoring the return value

And a whole load of compiler warnings. Worse yet, people who ignore warnings might ignore them.

> Now imagine the advances in error detection moving to languages that catch additional classes of errors.

Languages don't catch errors, tools do. The C tooling has been and still is constantly improving.

Lint was created for C in 1979 as the language authors saw how easy it was to make errors, static analysis is still largely ignored by the majority of C developers nowadays.

https://www.bell-labs.com/usr/dmr/www/chist.html

I am yet to see it being use in enterprise C code.

In projects with centralized build scripts, like most projects, hopefully they have -Werror or its equivalent on by default. I was speaking about the case were a group has systematically ignored warnings and they are already beyond fixing. This is a depressingly common state for many shops. The best fix I have seen to enable as many warnings as possible and treat them as errors as early in the project lifecycle as possible. For whatever reason C++ shops are much more likely to do this than C shops in my experience.

If the compiler isn't the "language" enough for you, then please explain how to write a buffer overflow in Javascript?

So I see this argument as "should the tools catch these things?". I suppose that would make some people feel better. But the fact is, when you're in the seat, it's up to you to make sure you Do No Harm.

But please be aware - generalizing all failures and integrating them into the tool suite is a pretty daunting task. Perhaps the economics of it make sense. But if you're stuck writing 'C', especially on legacy code bases with legacy tools, you're stuck, and there's only the one thing to do...

That did sum up my argument well, same one extreme you are taking.

You don't need the compiler or exception to cover all your errors. If you know something would be too costly to integrate in these mechanisms then you are free to disregard it. I have written throwaway code that did gross things with pointers, memory and system specific resources. But if I want code to last and be maintainable I do my best to get the compiler to watch my back.

This also works well when interfacing with legacy C. If the new code can be written in composable and unit testable classes, then you can prove (only to the extent of the quality of your automated tests) that problems are in your code or in the legacy code as they arise. Then when you find problems in legacy code, try to break a piece out and replace it with another class, even a a big ugly one just so you can get some unit tests in there. Then you can break the big ugly class into smaller, cleaner, composable and well tested units.