Hacker News new | ask | show | jobs
by hypeatei 1495 days ago
I'm not a C developer, nor have I ever been interested in developing with it.

From my perspective, it seems like a massive time drain and non-productive use of my time. Just a few points:

- Tooling seems all over the place (build system, package management)

- Having to roll your own trivial functions / types (tooling may play into this)

- Versioning is confusing (C99, C11, ???)

The only advantage I see would be in embedded software because C is supposedly supported on a lot of platforms and is performant. But, I'm not actually sure this is true in practice.

Can you write one file of C code and compile it easily for multiple platforms or is there a lot of caveats?

6 comments

What do you mean by 'time drain'? Do you know how much time it would take you to port your assembly code from x86 to ARM? And then when a new CPU comes out, you've got to rewrite all that assembly code again. Now that's a time drain. You could write your code once in C, and compile it for any CPU at this point. That's massive amount of your time saved.

Again, what do you mean by 'time drain'? Do you know how many human years were saved because 'grep' doesn't have to wait for the Java Hotspot VM to start up? If you spend an extra week to write a program that runs 10 seconds faster, you only need 14400 users to break even. If you've got a million users, you've singlehandedly saved humanity 115 _days_. That's a massive amount of time saved.

You must mean that you've got to code up some idea in whatever way possible so that it sees the light of day asap, regardless of how slow it is, how much energy it uses and how much disk space it consumes, because you need to sell something to someone. That's not what C is for.

C exists to write fast programs, not to write programs fast.

What I found is C compiles fast and produces small binaries.

Adding phat pointers, arrays, tagged unions, and closures to C would fix a lot of the current pain points without turning it into the disaster that is C++.

>C exists to write fast programs, not to write programs fast.

What if you want to write fast programs fast?

Also, while not useful for command line tools or for small run once programs, if the software is running continuously or its size is past a certain threshold, it might pay off to use .NET or Java since the speed is not that far of from C.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

Most programs are not benchmarks.
Do you mean to support what they wrote, or do you mean to refute what they wrote?
Been doing it for 15 years. C is a very stable target and easy to use. Portability doesn't come out of the box but is doable with a single abstraction library of your preference.
C is of course a terrible waste of time for most tasks today. It is performant and widely supported though. The main thing with it is that you simply cannot avoid it in certain areas, it's C or bust.

Now, let's talk about how much time C++ wastes ;)

> Can you write one file of C code and compile it easily for multiple platforms or is there a lot of caveats?

Target POSIX, and there's very few caveats. You're looking at portability as "how many processors can this run on". Think of it more as "how many places can use my library if I wrote it in C".

You're missing the major upside of writing in C: if you write your library in C, it is callable (with no changes) from Python, Ruby, Java, C++, C#, Lisp ... just about any language, really.

The language is so simple that an automated tool can be used to automatically generate bindings from your language of choice to C. I use Swig. Look into Swig.

You see C as an ancient dinosaur with no use, the reality is that it is usually the only real way to write reusable software[1].

[1] Sure, you can write in C++, but you'd still have to wrap it in C.

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.

> 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

Bye bye C.

Bye bye ehhh. Linux, Windows, OS X, Postgres, Android, Python, Sqlite, Redis...