Hacker News new | ask | show | jobs
by lumb63 1078 days ago
> There is nothing predictable about C except that you’ll eventually get screwed …

This has been the exact opposite of my experience. I’ve been writing C for 10 years and have yet to find a piece of code where I was surprised at what it did. That’s one thing I love about C, is it is entirely predictable. If it isn’t, my code is wrong. The language is rigorously specified. It is not hard to avoid undefined behavior.

Contrast that with languages like C++ or Python which hide gotchas all over the place. In Python, one cannot even rely on a variable being a certain type, and if it isn’t, the program explodes. C++ allows plus to not be the inverse to minus, allows for hidden custom memory allocators (overloading the new operator). Template metaprogramming is borderline sorcery past the simplest of use cases. C++’s interoperability with C is an accident waiting to happen with all the reallocations which can occur without the user being aware.

C lays flat out in front of the programmer all the unpredictable behavior that many other languages implement behind the programmer’s back. Sometimes that’s not desirable, and sometimes it is.

1 comments

I agree with your point about Python, which is why I'm glad type hints see adoption but dismayed that they're essentially fancy comments that don't enforce the actual runtime types.

The thing is, I'm not convinced avoiding UB is easy. E.g. what's the behavior of the following code?

    int16_t a = 20000;
    int16_t b = a + a;
Agreed on the dismay regarding type annotations. My opinion is that potentially misleading code which gives a sense of safety when none exists is worse than dangerous code. It lowers the programmer’s guards, which can lead to more bugs.

Integer overflow will result, I’m pretty sure. The largest value a signed 16 bit (so, 15 bit) can hold is 32767, IIRC.

I can see where that’s unexpected for people whose brains aren’t wired in powers of 2. This is one area where I think Rust improves upon C, with its availability of overflow detection in arithmetic. It’s unfortunately verbose, but it enables greater safety.

Not quite what I was getting at: On an implementation with 32-bit ints, the code is valid – the values get promoted to 32 bit, added and then truncated to 16 bit. Yet on a platform with 16-bit ints (and microchips & unusual platforms is a frequently stated reason for using C), the addition overflows and result in UB.

Luckily most other languages haven't decided to copy C's implicit promotion rules & target-dependant integer sizes.

Given that all arithmetic autopromotes to int if smaller than int, there's no undefined behavior in this code if int is 32-bits (which is true on most systems).