Live data from Hacker News

How can C Programs be so Reliable? (2008)

tratt.net

91–97 of 97 posts

Re: How can C Programs be so Reliable? (2008)

#91

Earlier quoted context omitted.

> While I agree with last two paragraphs, C is not good even for that purpose because it doesn't give any tool to manage them. That is the reason it should be used as a learning tool. So that you know the nitty gritty details without anyone "managing" it away from you.

Then learn an assembly language instead, because C also has a fair amount of bookkeeping hidden behind the scene. C is typically described as a "low-level" programming language, where the "low-level" normally refers to the supposed distance from the language to the actual hardware. But as many incidents with UB demonstrate, this distance is still quite larger than expected. I think there is another sense of the word…

> C also has a fair amount of bookkeeping hidden behind the scene

Hosted C does in the form of the standard library. C does have a freestanding variant though and its book keeping is generally limited to knowing struct member offsets.

Re: How can C Programs be so Reliable? (2008)

#92
post #74

Earlier quoted context omitted.

Static typing is useless without strict typing. Knowing the type of everything won’t save you if you can multiply a pointer by an integer and use the result as a file handle.

> Static typing is useless without strict typing. Knowing the type of everything won’t save you if you can multiply a pointer by an integer and use the result as a file handle. What language are you talking about? Go to godbolt and try that with any of the compilers there for C or C++.

Compiles with only a warning:

    #include 
    int main() {
      int x = 5;
      int y = &x;
      FILE *f = x * y;
      fputs("hello", f);
    }

Re: How can C Programs be so Reliable? (2008)

#93
post #92

Earlier quoted context omitted.

> Static typing is useless without strict typing. Knowing the type of everything won’t save you if you can multiply a pointer by an integer and use the result as a file handle. What language are you talking about? Go to godbolt and try that with any of the compilers there for C or C++.

Compiles with only a warning: #include int main() { int x = 5; int y = &x; FILE *f = x * y; fputs("hello", f); }

So what are you complaining about? That the compiler told you "Don't do that" but you ignored it?

I mean, you said:

>> Knowing the type of everything won’t save you

but the compiler is trying to save you! You have to actively work against it in order to hang yourself, and you blame the language?

Re: How can C Programs be so Reliable? (2008)

#94
post #28

Earlier quoted context omitted.

Back when every developer had to build their own failure detection code and display messages to help themselves debug anything that meant that almost every developer was good at communicating errors to the user. Today developers don't build that skill, so you see applications that just fails silently everywhere or produce nonsense errors. The better developer tools you have the less your developers will need to learn…

Back in those days the error you got was "Segmentation fault (core dumped)" Now its an exact line number with a little description of what went wrong and sometimes a suggestion on how to fix it.

Agreed. And the example of crashing due to a NULL file descriptor is in the minority. Often C error handling involves checking errno. This is routinely ignored, and when some call "fails", the code continues to some point later where things don't quite work right. When this happens, it's usually much harder to determine the cause, given that the root failure context is gone.

I'm my experience, C developers sometimes just dislike exceptions in other languages because exceptions defy C code path expectations. That was my first instinct when going from C to other languages. And so additional arguments against exceptions are put forth, including performance issues (which are real) and this idea of paranoia being better than language tooling (which is rather suspect imo).

Re: How can C Programs be so Reliable? (2008)

#95

Earlier quoted context omitted.

> You don't necessarily crash if you failed to perform a NULL check! In the case of using the result from `fopen`, I don't know of a platform where a dereferencing of NULL (which happens in a separate translation unit, which is already compiled and linked, and will not be subject to LTO and other optimisations) within the various read/write/seek/tell functions doesn't result in an immediate crash. I fully admit that…

> I don't know of a platform where a dereferencing of NULL (which happens in a separate translation unit, which is already compiled and linked, and will not be subject to LTO and other optimisations) within the various read/write/seek/tell functions doesn't result in an immediate crash. Although in a very different content, I have seen "dereferencing" a null pointer in C++ not crash immediately, if you dereference it…

> Although in a very different content, I have seen "dereferencing" a null pointer in C++ not crash immediately,

I don't think this is possible at all in C, which doesn't have classes, and the sophisticated following of pointers to find a method.

Re: How can C Programs be so Reliable? (2008)

#96

Earlier quoted context omitted.

Back in those days the error you got was "Segmentation fault (core dumped)" Now its an exact line number with a little description of what went wrong and sometimes a suggestion on how to fix it.

Agreed. And the example of crashing due to a NULL file descriptor is in the minority. Often C error handling involves checking errno. This is routinely ignored, and when some call "fails", the code continues to some point later where things don't quite work right. When this happens, it's usually much harder to determine the cause, given that the root failure context is gone. I'm my experience, C developers sometimes…

> And so additional arguments against exceptions are put forth, including performance issues (which are real) and this idea of paranoia being better than language tooling (which is rather suspect imo).

I feel you are mischaracterising my position, which was to have graduating students work in C for a non-trivial amount of time before they moved on to a new language.

The argument that paranoia is better than language tooling is entirely absent from my arguments.

Re: How can C Programs be so Reliable? (2008)

#97

Earlier quoted context omitted.

Most interesting parts of US government will buy and consume software written in C++ without qualification or reservation for the indefinite future. People are wishcasting, it isn’t a serious risk. New systems are being planned in C++ today and language choice isn’t even mentioned. Parts of government have a lot of experience with C++ in high reliability contexts. There are many advanced systems in government written…

> Rust is often not a good fit for the software architectures required unless you are comfortable writing a lot of awkward unsafe code. If you have to write "a lot of awkward unsafe code" in Rust, you're doing something wrong. I use C++ rather than Rust, but any time I'm implementing any sort of non-trivial data structure or inter-thread communication, I encapsulate it in a "safe" interface that is impossible to misu…

You are misunderstanding, there is no other way to write this code. Even in C++ you have to do a bit of awkward stuff to make the compiler do what you want. The main issue is that lifetimes and ownership do not and cannot follow the object model of the programming language, and both are intrinsically not fully observable at compile-time, being solely resolvable at runtime. Recent versions of C++ have started adding first-class support for object models with these properties so hopefully this will become easier.

The base case here is user-space virtual memory, which is de rigueur for high-scale data intensive applications. Objects not only don't have a fixed address over their lifetime even if you never (logically) move them, they often don't have an address at all, and when they next have an actual memory address it may materialize in another thread/process's address space. And hardware can own references to and operate on this memory outside the object model (e.g. DMA). The silicon doesn't respect the programming language's concept of an object because it doesn't know objects exist. You have to design non-trivial async scheduling and memory fix-up mechanics to make all of this reasonably transparent at the object level. It is actually a pretty elegant model, complex compiler negotiations notwithstanding.

And of course, the reason we put up with the implementation complexity is that there is a huge gap in scalability/performance between this and the alternatives. Same reason people use thread-per-core software architectures. It works around some fairly deep limitations in the silicon and OS.

Post reply on HN