Live data from Hacker News

The Development of the C Language (1993)

bell-labs.com

141–150 of 536 posts

Re: The Development of the C Language (1993)

#141

Earlier quoted context omitted.

Tell me an alternative which ticks all the checkboxes and I'll switch immediately. C++ isn't it because the committee has completely lost focus since ca C++11, Rust isn't it because they completely forgot about ergonomics, simplicity and elegance on their quest to fix memory safety (and both C++ and Rust suffer from "design by committee"). Zig looks perfect so far, but it's too early to switch over yet. Any other pro…

You didn't say what the checkboxes are, but... perhaps the 'BetterC' subset of D? https://dlang.org/spec/betterc.html#retained Or D itself if you don't need a language as minimal as C. D is basically C++ redesigned and now that GCC includes D support by default I wonder whether it'll gain popularity.

Definitely an option, and D is actually one of the languages I haven't seriously looked into yet (or rather, I saw it as a C++ alternative in its heydays ca 2005 and that image stuck in my head - and at that time I hadn't been looking for a C++ alternative)

PS: my main use of C is currently to write platform abstraction libraries with minimal size and runtime overhead, so need to talk directly to operating system APIs, plus WASM is a very important target. The libraries must be usable from other languages via automatic bindings generation (quite simple with a C API). Also for performance-oriented stuff, direct control over memory layout and lifetimes please.

Also personal opinion from 20 years of C++ experience: high level abstractions never pay off in the long run. Simple imperative code always wins when it comes to "malleability".

Re: The Development of the C Language (1993)

#142
post #114

Earlier quoted context omitted.

> You don't have to use an inefficient solution. You can always roll your own optimized solution or use a library That’s not true. You for example can’t write a generic, efficient vector implementation in C - the language itself can’t do that. You either have to copy paste the same code for different sizes, or make use of some monstrous hack of a macro. Instead projects use hacks like conventionally placing the next/…

Generic things are rarely efficient, the most optimal code tends to be specialized and tailored to specific hardware and/or the kind of data its operating on. std::vector (which is a really inefficient way of doing dynamic arrays btw) can be cleanly implemented with macros (see stb stretchy buf) or by splitting the element data from the housekeeping data: int append(void *arr, size_t elemsize, size_t *capacity, size_…

Six arguments - seriously? Avoiding that is the point of generic programming, and probably more efficient there too

Re: The Development of the C Language (1993)

#143
post #114

Earlier quoted context omitted.

> You don't have to use an inefficient solution. You can always roll your own optimized solution or use a library That’s not true. You for example can’t write a generic, efficient vector implementation in C - the language itself can’t do that. You either have to copy paste the same code for different sizes, or make use of some monstrous hack of a macro. Instead projects use hacks like conventionally placing the next/…

You're talking about something that isn't related to efficiency. Copy and pasting, macros, generating code -- none of these preclude producing an efficient solution. There is nothing in C++ that is inherently more efficient than C.

Except that more efficient solutions can be implemented much more practically? Solutions that you'd need to bend over backwards for in C?

Re: The Development of the C Language (1993)

#144
post #114

Earlier quoted context omitted.

> You don't have to use an inefficient solution. You can always roll your own optimized solution or use a library That’s not true. You for example can’t write a generic, efficient vector implementation in C - the language itself can’t do that. You either have to copy paste the same code for different sizes, or make use of some monstrous hack of a macro. Instead projects use hacks like conventionally placing the next/…

> hacks like conventionally placing the next/prev pointer in structs This is not a hack, it is the way it should be in C.

Except that that's a linked list and not an array.

Re: The Development of the C Language (1993)

#145
post #79

Earlier quoted context omitted.

> I really hate how for microcontrollers the only two choices are either C++ or Micropython Why wouldn't you just use C for programming a microcontroller? Sure, it's not a great language for web backends, but microcontrollers are where it shines. You're probably not deploying 100,000 lines to a microcontroller for a personal project, so the lack of certain abstractions isn't going to be that painful. On the other han…

Why wouldn't you use assembly for programming a microcontroller? Sure, it's not a great language for web backends but microcontrollers are where it shines. /s Because as the OP states, it's an objectively (pun intended) terribly abstracted language. There is nothing 100% predictable about C except that you'll eventually get screwed because you didn't account for some random obscure thing that should never have even b…

> 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.

Re: The Development of the C Language (1993)

#146

Earlier quoted context omitted.

Enable max warning level, use a static analyzer, and ASAN, UBSAN and TSAN (in order of importance), and most problems you listed just disappear. Most importantly though: don't use MSVC if you have the choice.

Yeah if you want to kill yourself from frustrations, maybe. I'm not writing microcontroller code for the fucking space shuttle, and I would suspect most people aren't. C did a ton of things right, but it also did a ton of things wrong. Learning from that and moving on would be the sensible thing to do after 50 years.

> Yeah if you want to kill yourself from frustrations, maybe. I'm not writing microcontroller code for the fucking space shuttle, and I would suspect most people aren't.

You're really exaggerating the problems. Does your negative opinion of C come from experience, or did you listen to the Rust evangelists who have an incentive to make the difficulty appear bigger than it is? Because it hasn't been my experience that C is this huge minefield of bugs that are impossible to explain or debug. You prevent a lot of bugs by actually understanding the language instead of coding by trial-and-error, the remaining bugs usually get caught quickly if you use an advanced compiler like GCC or Clang with the right flags (warnings and sanitizers), and for the occasional bug that slips through, the debugger tends to be helpful.

It's true that C has a bunch of historical footguns like gets and strcpy that you need to avoid. It's a very bad language to learn by trying random things and seeing what works. However, it's possible for a "mere mortal" to write good code. You just need to do more up-front learning than you could get away with in e.g. Python. If you pick a good book and listen to experienced programmers, they will tell you what to do and what to avoid.

And regarding abstraction—you can go very far with just structs and pointers, but you have to do things the C way rather than trying to write Java in C. If it's enough for Linux devs and their millions of lines of code, it will be enough for your personal microcontroller projects.

There is a very promising contender in the low level space that aims to fix some of C's problems, it's a new language called Zig. However, it's at a pretty early stage; even if it catches on, it will be many years from now. Right now, if you want to do low level work, you'll benefit from becoming good at C.

Re: The Development of the C Language (1993)

#147
post #80
post #68

Earlier quoted context omitted.

1. It gives me a lot of control over how the program works, which lets me create programs that work faster and use less memory than would be possible in most other languages. 2. Relatedly, it's more explicit than almost any other language. If a line of code doesn't look like a function call, it's not calling anything. There is no hidden control flow. These statements are not true in languages which support operator o…

> It gives me a lot of control over how the program works, which lets me create programs that work faster and use less memory than would be possible in most other languages. While it is true to a degree, I would also add that due to its low level of expressivity, you often have to introduce less efficient solutions simply because language deficiencies. Things like small string optimizations in C++ are simply not poss…

C is an expressive language when you’re not working with strings and memory the way you do in most HLLs. Almost all operators return a value and can be nested in sub-expressions. Assignments and pre/post increments/decrements are expressions. The comma operator evaluates expressions in the given order and returns a value. There is a GNU extension called “statement expressions”, allowing you to define function-like macros.

Re: The Development of the C Language (1993)

#148
post #68
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

1. It gives me a lot of control over how the program works, which lets me create programs that work faster and use less memory than would be possible in most other languages. 2. Relatedly, it's more explicit than almost any other language. If a line of code doesn't look like a function call, it's not calling anything. There is no hidden control flow. These statements are not true in languages which support operator o…

> If a line of code doesn't look like a function call, it's not calling anything.

Why is that important to you?

Re: The Development of the C Language (1993)

#149
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

Because most of the projects I want to work on are in C. Postgres, the Linux kernel, lots of legacy systems stuff. All the foundations of our field are in C, so that's what I use when I want to contribute or study them.

Re: The Development of the C Language (1993)

#150
post #6

People who still write C, honest question: Why? C is full of quirks. From cryptic "undefined behaviors" to a type system that isn't really a type system (more like "size hints for the compiler"), the language doesn't feel easy to use/debug. Add to this CPP macros, a universally recognized bad idea, a clunky import system, and lack of a single reference implementation of the compiler/libC, and you have a language that…

Honestly because I don't want to learn another language. And because most of the world uses C for low level stuff. You can say that Esperanto is a much better international language than English but what good does it do if nobody speaks it?

Veering off topic, there is a great rant about why Esperanto is a horrible international language: https://web.archive.org/web/20110515155117/http://www.xibalb...
Post reply on HN