Live data from Hacker News

Who Says C is Simple? (2010)

eecs.berkeley.edu

41–50 of 59 posts

Re: Who Says C is Simple? (2010)

#41
post #20

C is simple to compile into nearly-optimal code, or at least it was back in the 1970s, when computers had single-opcode dispatch or trivial pipelines, no SIMD hardware, no other parallelism worth mentioning, and it wasn't worth worrying about cache too much. (Running in the registers was a neater trick.) That meant it was relatively simple to 'see' the assembly language 'behind' a given C function or stretch of code;…

"C is simple to compile into nearly-optimal code, or at least it was back in the 1970s," And yet the best practice of the time was not to use C for time-critical applications. If your hypothesis were true, why would, say, all those NES programmers write all that assembly?

He means it was nearly-optimal on its original target, the PDP 11.

It was decidedly not nearly-optimal a few years later on microprocessors like 8080, z80, 6502, etc., which were highly register starved, 8-bit rather than 16-bit, non-orthogonal instructions and registers, etc.

As for "not to use C for time-critical applications", both then and now people sometimes write critical inner loops in assembly, it's just less common now because compilers are much more sophisticated.

But C was indeed used on "time-critical applications", aside perhaps from inner loops, back in the 70s, certainly on PDP 11s, and sometimes on less ideal microprocessors.

> why would, say, all those NES programmers write all that assembly?

Several reasons. First and foremost, things like that were highly RAM starved by the standards of the day. The PDP-11/70 had 64k of instructions and a separate 64k of data per process, with a total amount of RAM of up to something like a megabyte.

The NES had 2k RAM onboard -- although cartridges could extend that -- and the register starved 6502.

Another big reason is that, in every era, games are always pushing the limits of the hardware, and developers were typically quite willing to code in assembly if they believed it would give them a 20% edge in speed or decrease in space.

But also there was a mythos (that hasn't completely disappeared) that assembly would yield vastly more than 10%-20% speed increase over high level languages of the day, including C, so for most developers, they never even considered anything but assembler.

It also was not uncommon at the time for many of those game programmers to only know assembler, and not any other language except perhaps Basic.

The availability of C compilers for various platforms was not so universal then as it is now, especially on non-Unix systems, and the non-Unix C compilers, when available, were not necessarily at the same level of quality as the Unix C compilers.

Last but not least, C had not yet taken the world by storm, and a lot of those developers and companies had never even heard of C, and the ones that had heard of it were pretty dubious, more often than not.

Re: Who Says C is Simple? (2010)

#42

All of the examples here are really horrible code. This is the second article in a few days on Hacker News to list out a few examples of how hard C is. And for little reason; there's absolutely no value in being able to write something like: return ({goto L; 0;}) && ({L: 5;}); It probably has a bug, will be hard to debug, and isn't more performant than writing it in a clearer way. And unfortunately, while the example…

> This points to a need for a new language that avoids these issues.

They already existed back when C was UNIX only, but then UNIX became widespread....

Re: Who Says C is Simple? (2010)

#43

Earlier quoted context omitted.

"C is simple to compile into nearly-optimal code, or at least it was back in the 1970s," And yet the best practice of the time was not to use C for time-critical applications. If your hypothesis were true, why would, say, all those NES programmers write all that assembly?

He means it was nearly-optimal on its original target, the PDP 11. It was decidedly not nearly-optimal a few years later on microprocessors like 8080, z80, 6502, etc., which were highly register starved, 8-bit rather than 16-bit, non-orthogonal instructions and registers, etc. As for "not to use C for time-critical applications", both then and now people sometimes write critical inner loops in assembly, it's just les…

> Last but not least, C had not yet taken the world by storm, and a lot of those developers and companies had never even heard of C, and the ones that had heard of it were pretty dubious, more often than not.

Specially since some of us were exposed to languages (Modula-2, Turbo Pascal) that were more feature rich than C while allowing similar performance levels on the same systems.

Re: Who Says C is Simple? (2010)

#44

All of the examples here are really horrible code. This is the second article in a few days on Hacker News to list out a few examples of how hard C is. And for little reason; there's absolutely no value in being able to write something like: return ({goto L; 0;}) && ({L: 5;}); It probably has a bug, will be hard to debug, and isn't more performant than writing it in a clearer way. And unfortunately, while the example…

This is odd, GCC documentation clearly states that jumping into statement expression is not permitted. It is properly identified as error when compiling as c file, but no errors are given when compiled as c++ file. https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

Re: Who Says C is Simple? (2010)

#45

All of the examples here are really horrible code. This is the second article in a few days on Hacker News to list out a few examples of how hard C is. And for little reason; there's absolutely no value in being able to write something like: return ({goto L; 0;}) && ({L: 5;}); It probably has a bug, will be hard to debug, and isn't more performant than writing it in a clearer way. And unfortunately, while the example…

> This points to a need for a new language that avoids these issues. I think Rust is the answer, but I would like to see more languages try to fill that gap--competition is healthy.

Programs written in C and C++ may have issues because the languages assume the programmer knows what they are doing. This assumption leads to some great solutions to hard problems because the programmer is essentially free to do what they want.

Of course, this assumption, as with most others, doesn't always hold true. This doesn't mean there is a problem with the language. The problem is with the programmer.

If you're going to write something like "return ({goto L; 0;}) && ({L: 5;});", no language is going to save you.

C and C++ are still used today, in part, because modern languages try to restrict the programmer. Rather than assume the programmer knows what they are doing, they assume the programmer is stupid and needs help to cross the road. By assuming stupidity, the restrictions modern languages put in place prohibit certain solutions and as such C and C++ will remain the go-to systems languages.

We do not need new languages. What we need is programmers who won't abuse the languages we already have.

Re: Who Says C is Simple? (2010)

#46

All of the examples here are really horrible code. This is the second article in a few days on Hacker News to list out a few examples of how hard C is. And for little reason; there's absolutely no value in being able to write something like: return ({goto L; 0;}) && ({L: 5;}); It probably has a bug, will be hard to debug, and isn't more performant than writing it in a clearer way. And unfortunately, while the example…

[deleted]

Re: Who Says C is Simple? (2010)

#47
post #11

Earlier quoted context omitted.

No they don't. What UB do you think they invoke? They do invoke implementation defined behaviour, but not undefined.

An uninitialized variable is UB, not implementation-defined. Thus, the compiler is free to treat the variable as though it doesn't have a value at all, or change it's value at will. It's not uncommon for the value of an uninitalized variable to change at strange places in the code that you wouldn't expect, because the compiler initially said "Variable x will be kept in register %eax", but then without a value to init…

What evidence do you have that it's an uninitialized variable?

It's a code fragment; it's not in a function body. The way I read it, it was simply to document the type of x. 'x' could be a global for all we know.

Re: Who Says C is Simple? (2010)

#48
post #22

Earlier quoted context omitted.

It really only depends on if you define simple as "can only derive simple results." And, you do realize that one of the simplest languages for compiler writers, lisp, doesn't have to move heaven/earth to make that calculation work out how you want it.

> And, you do realize that one of the simplest languages for compiler writers, lisp, doesn't have to move heaven/earth to make that calculation work out how you want it. I've written a C compiler and am currently writing a Lisp compiler, and I'm not sure where you get the idea that Lisp is a simple language for compiler writers. Lisp's simple representation belies a very complicated runtime, to the point that the maj…

This seems to get back to the other debate that crops up with "simplest." Just because I posit that it is one of the simplest languages, does not mean I imply it is by definition simple.

Re: Who Says C is Simple? (2010)

#49
post #43

Earlier quoted context omitted.

He means it was nearly-optimal on its original target, the PDP 11. It was decidedly not nearly-optimal a few years later on microprocessors like 8080, z80, 6502, etc., which were highly register starved, 8-bit rather than 16-bit, non-orthogonal instructions and registers, etc. As for "not to use C for time-critical applications", both then and now people sometimes write critical inner loops in assembly, it's just les…

> Last but not least, C had not yet taken the world by storm, and a lot of those developers and companies had never even heard of C, and the ones that had heard of it were pretty dubious, more often than not. Specially since some of us were exposed to languages (Modula-2, Turbo Pascal) that were more feature rich than C while allowing similar performance levels on the same systems.

Certainly, although of course it depends on which range of years we're talking about, and which platforms we're talking about; you're talking about later years than PDP 11 C and more capable platforms than the "NES" mentioned above.

Prior to Turbo Pascal there was UCSD Pascal, which was extremely popular but not high performance.

But the whole idea that any high level language could be even close to competitive with assembly was a very radical idea considered laughable by the mainstream, for many years, which I think is the underlying idea here.

Another language worth mentioning is Bliss, a pioneering high level systems programming language roughly contemporary with early C, with high levels of efficiency and optimization, and was famous in some circles but not with the mainstream.

As I recall, that one eventually dropped by the wayside because it was too closely tied to DEC architectures. It may or may not have been ported to others, but it did not have (relatively) easy portability as a feature anyway, unlike the Johnson C compiler, which is often claimed to be the first such.

I wasn't a Turbo Pascal user, but wasn't it, too, tied to the one platform?

Wirth's languages after Pascal, I dunno; everyone heard of them but they were never that widely adopted. I guess I'm unclear on why.

Re: Who Says C is Simple? (2010)

#50

All of the examples here are really horrible code. This is the second article in a few days on Hacker News to list out a few examples of how hard C is. And for little reason; there's absolutely no value in being able to write something like: return ({goto L; 0;}) && ({L: 5;}); It probably has a bug, will be hard to debug, and isn't more performant than writing it in a clearer way. And unfortunately, while the example…

> This points to a need for a new language that avoids these issues. I think Rust is the answer, but I would like to see more languages try to fill that gap--competition is healthy. Programs written in C and C++ may have issues because the languages assume the programmer knows what they are doing. This assumption leads to some great solutions to hard problems because the programmer is essentially free to do what they…

In Rust, programmers are also "essentially free to do what they want", you just need to explicitly declare the parts of your code where you know better than the type system. The pertinent difference is Rust is memory-safe by default, and forces you to opt-in to unsafety and undefined behavior so that those pieces of code in particular can be more closely audited.
Post reply on HN