Hacker News new | ask | show | jobs
by sylware 1493 days ago
C is supposely a language which it is reasonable to write a compiler for and in order to get a reasonable hardware ISA abstraction.

Don't worry, the ISO working groups are making sure that it won't last and soon writting a C compiler will become a nightmare like what they did for c++ (C23 is seriously scary).

Instead they should fix it: remove _Generic, typeof, etc which have nothing to do there, and make sure writting a C compiler does keep requiring only a reasonable amount of developement efforts (not an army of devs for 20 years like c++).

Actually, removing and hardening stuff would be more appropriate, namely not really adding stuff: remove typedef? harden and improve the type casting rules, let's be bold and eat the bullet, remove the implicit cast except to/from void* pointers and add static/dynamic casts (please not with the c++ syntax)? Make function pointers the same than the other pointers, finally (POSIX/GNU requires it though). Etc.

3 comments

> Instead they should fix it: remove _Generic, typeof, etc which have nothing to do there, and make sure writting a C compiler does keep requiring only a reasonable amount of developement efforts (not an army of devs for 20 years like c++).

Have you ever written a C compiler? These things are not difficult to support. You sound more interested in just removing things that are "new" that you don't really like than genuinely concerned about things that are complex to implement, like passing structs around while keeping the platform ABI in mind, and handling the intricacies of bitfields.

I agree C23 is scary (1000+ new functions???), but your complaint seems a bit misplaced. For example `typeof` is a GNU extension, and removing `typedef` will instantly break virtually everything (which is not only used to remove `struct`/`union`/`enum` from the name). And a reasonable C compiler can only do a very limited amount of optimization, which precludes a majority of current C uses.
It looks like typeof() is being added it C23, so his complaint about it sort of makes sense.

I say "sort of" because if he's truly concerned about the effort involved in creating independent implementations, then obviously he should be evaluating features by the difficulty involved in implementing them. typedef and typeof are absolutely trivial to implement [0] [1]. typedef just creates type aliases and typeof is very similar to sizeof.

Also, I'm not sure what 1000 functions you're referring to, but most functions being added are already in POSIX and already exist in a huge number of independent libc implementations. There are dozens of POSIX libcs, including at least 5 totally independent implementations for Linux alone that are still fully maintained and under active development.

[0]: typeof: https://github.com/rui314/chibicc/commit/7d80a5136d1b2926dd0...

[1]: typedef: https://github.com/rui314/chibicc/commit/a6b82da1ae9eefa44da...

> It looks like typeof() is being added it C23, so his complaint about it sort of makes sense.

To my knowledge typeof was discussed but not adopted to C23, but well, yeah, the proposal is still being updated as of February [1] so it's still on the table. Your argument with chibicc is actually great, though I personally think typeof is too much (in the same reason I think _Generic and <tgmath.h> is too much: they only solve overly specific problems).

> Also, I'm not sure what 1000 functions you're referring to, [...]

This one was my slight misunderstanding. I should have said 200+ functions, and they mostly come from the updated IEEE 754 standard and additional floating point and decimal types [2]. 1000 was the number of additional reserved identifiers. Still I feel uncomfortable about this sudden explosion in the single global namespace of C.

[1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2927.htm

[2] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2426.pdf#p...

Keeping it simple to write a compiler is not a serious use case these days. People aren't bootstrapping new platforms from scratch. GCC and Clang are anything but simple.
Even if they aren't, people absolutely should be able to bootstrap new platforms from scratch. It's important to have confidence in our tools, in our ability to rebuild from scratch, and to be safe against the "trusting trust" attack among other things.

Lately I've been catching up on the state of the art in bootstrapping. Check out the live-bootstrap project. stage0 starts with a seed "compiler" of a couple hundred bytes that basically turns hex codes into bytes while stripping comments. A series of such text files per architecture work their way up to a full macro assembler, which is then used to write a mostly architecture-independent minimal C compiler, which then builds a larger compiler written in this subset of C. This then bootstraps a Scheme in which a full C compiler (mescc) is written, which then builds TinyCC, which then builds GCC 4, which works its way up to modern GCC for C++... It's a fascinating read:

https://github.com/oriansj/stage0

https://github.com/fosslinux/live-bootstrap/blob/master/part...

Even if no one is "using" this it should still be a primary motivator for keeping C simple.

There are multiple standards for C. C23 does not replace C17, or C11, or C99, or even C89. Maybe something should replace C89, but that's another discussion. I'd vote for C99 as a minimum target and prefer C11.

Just as you yourself described, one can absolutely target a platform from scratch with C99, Forth, Lua, a Pascal, a modernish Basic dialect, or some form of Lisp without building the largest, most modern compiler first. Once you have a compiler or even an interpreter for any of those, one can use it to create a compiler for something bigger and more modern. In fact, that's precisely where C was originally targeted - as a portable bootstrap language to various hardware platforms.

On the other hand, one can also target a new platform via LLVM. Both options have their merits and drawbacks.

> Keeping it simple to write a compiler is not a serious use case these days.

The implication is that if it is simple to write a parser for a language, then the language is simple to read.

Lisp and Scheme seem to discourage this sort of thinking in a great many programmers. After all, Lisps often start as just the eval function for their S-expressions and grow from there.

See also: Brainfuck, Forth, Chinese

Easy != Simple

Linking this makes me nostalgic for 2010 :)

https://www.youtube.com/watch?v=SxdOUGdseq4