Live data from Hacker News

“C is how the computer works” is a dangerous mindset for C programmers

words.steveklabnik.com

121–130 of 387 posts

Re: “C is how the computer works” is a dangerous mindset for C programmers

#121

Wait until they learn that machine code is not exactly how the computer works either. The hardware is doing things to your code you might not expect.

Hence the massively upvoted SO thread ;p : https://stackoverflow.com/questions/11227809/why-is-processi...

Re: “C is how the computer works” is a dangerous mindset for C programmers

#123
One of the blog posts I keep meaning to write is in the vein of "Why C is not portable assembly." Ironically, most of my points about C failures aren't related to UB at all, but rather the fact that C's internal model doesn't comport well to important details about machines:

* There's no distinction between registers and memory in C. A function parameter that is "register volatile _Atomic int" is completely legal and also makes absolutely no sense if you want C to be a "thin" abstraction over assembly.

* There's no "bitcast" operator that changes the type of a value without affecting the value. The most common workaround involves going through memory and praying the compiler will optimize that away (while violating strict aliasing semantics to boot).

* No support for multiple return values (in registers). There's structs, but that means returning via memory because, well, see point 1.

* Missing machine state in the form of vector support (which is where the lack of the bitcast becomes particularly annoying). The floating-point environment is also commonly poorly supported.

* Missing operations such as popcount, cttz, simultaneous div/rem, or rotates.

* Traps are UB instead of having more predictable semantics.

* No support for various kinds of coroutines. setjmp/longjmp is the limit. You can't write zero-cost exception handling in C code, for example. Even computed-goto (a source-level equivalent of jump to a location held in a register) has no C representation, though it is present in some compiler extensions.

Re: “C is how the computer works” is a dangerous mindset for C programmers

#124
A good way to think of it is that C is how computers worked 40 years ago.

A lot has changed since then, but computers put up a lot of effort to pretend that they still work similarly, and most other programming languages have put up a lot of effort to figure out how to make things work for a "C computer".

Re: “C is how the computer works” is a dangerous mindset for C programmers

#125

C is like water. Atomically it is the DNA of all other programming languages. There's a reason why C is generally the fastest language with smaller binaries, and there's a reason why language like Python fallback to C for doing anything processor intensive. C will still be here when the latest fad languages of today are long forgotten.

In clojureland we fallback to java for doing anything processor intensive.

Re: “C is how the computer works” is a dangerous mindset for C programmers

#126

Earlier quoted context omitted.

It would also be nice if Rust had a specification. Without a spec it's impossible to build a correct alternative Rust implementation.

Just pains me that the Rust team is so oblivious to the fact that they need a spec if they ever hope to have a chance to replace C.

We are not oblivious. First of all, we are not really trying "to replace C." Second, a tremendous amount of work has been put into specifying Rust. It's just also a tremendous amount of work. Like, "the EU has given grants of millions of Euro towards working on it but we're still not done" amounts of effort.

C did not have a standard for 18 years, it was first created in 1972, and ANSI C didn't appear until the spring of 1990. I'm not suggesting that it took them 18 years to write a spec, it's that it wasn't really needed for a long time. Expecting Rust to have one after five years is aggressive. Some languages have done this! I think we'll end up somewhere between what C did and what C# did, in this regard.

Re: “C is how the computer works” is a dangerous mindset for C programmers

#127
post #88

Earlier quoted context omitted.

No, it really isn't on anything modern, like ARM SoCs or x86 CPUs. The number of times I've hit my head to wall trying to understand what the heck the CPU is doing for a given sequence of instructions, like why the number of cycles or memory bandwidth required is way different from my expectation. A modern CPU willy nilly reorders instructions, stores, and creates new "virtual" registers out of thin air to dissolve s…

Can you give an example? The most complicated assembly->microcode examples I can think of are floating-point instructions like FSIN that run CORDIC loops under the hood, and those are still pretty easy to reason about.

Pseudo-code:

  a = 10;
  b = 20;
  c = b + 30;
  bar = a + b;

  x = 1;
  y = 2;
  z = y + 3;
  foo = x + y;
... in order to remove dependency stalls might be executed as:

  b = 20;
  y = 2;
  a = 10;
  x = 1;
  c = b + 30;
  z = y + 3;
  bar = a + b;
  foo = x + y;
This would still be true, even if 'x' and 'a', 'y' and 'b' etc. variables (well, registers) had same name. In that case CPU would just make up new "variables" as required and do the same transformation!

Re: “C is how the computer works” is a dangerous mindset for C programmers

#128

To be fair, even assembly language isn't how the computer works (gets translated into micro code). Not to mention other integral components like the GPU that are coded in an entirely different model. I think what's fair to say is: the "abstract C machine" tends to have a minimal amount of concepts on top of the machines instruction set, compared to other languages, and generally provides the least friction if you nee…

Not really, assembly language is extremely close to microcode, much much closer than it is to C. C has a whole bunch of baggage like pointer provenance, inability to read uninitialized memory, doesn't understand cache aliasing, etc that don't fit hardware well.

Microcode is not used for the majority of operations. Are you confusing it with micro-ops?

Re: “C is how the computer works” is a dangerous mindset for C programmers

#129
I think the biggest point where C is more "how the computer works" vs. a lot of languages is when you write an allocator.

I've noticed in, say, an interview context, that people without a lot of C experience have a lot of trouble reasoning about how an allocator might work, or where memory comes from, or even that some constructs in their preferred language result in memory allocation. With C you can't hide these details.

Yes there are abstractions beneath you, both in software (your OS has set up the MMU) and hardware (cache, out of order execution) and also in the C standard itself (assumptions about pointer types, the precise meaning of the stack). This doesn't take away from the point that reasoning about allocations is more of a thing.

Re: “C is how the computer works” is a dangerous mindset for C programmers

#130

Earlier quoted context omitted.

I feel your statement is actually much closer to the danger. C is pretty close to the hardware indeed and that misleads people into thinking that C is actually exactly how the hardware works. It's a very easy trap to fall into and I've seen many colleagues do just that.

So no disrespect to your colleagues, but they work in C and don't understand the relationships between C --> ASM --> Machine Code --> Hardware? That's... disturbing. Hope they're not building medical devices.

My point was that many people who just now come into C fall into the trap of thinking that it [almost] exactly mimics hardware. Which is an easy mistake to make if you are new to the thing because it's taught as if it's a panacea and sadly many people believe those university courses.

As for former colleagues, oh well, we all learn and grow. I chose to bail out because something as non-deterministic as a C's code stability when cross-compiled for anything more than two systems turned me off. Different strokes, different people.

Post reply on HN