Only if you ignore
1. variadic arguments as in printf,
2. function pointers which are a very elementary (type-unsafe) form of closures,
3. a nice way of casting to void
4. setjmp and longjmp goodies (?) which allow you to code up co-routine libraries and exception handling mechanisms
I'm sure there are more such facets I am missing.
The elegance of the specification may be questionable, but the scope of what C tried to achieve is breathtaking. It actually is superior to most of its improvements.
I identify with @antirez's sentiment. I know both C and C++ very well. I find C definitely more artistic. C++ is utilitarian.
Prolog is the other language I code in "artistically". It too is quite simple and constrained, though it is on the opposite end of the high/low-level spectrum as C.
I would argue that C++ can be dramatically more deceiving than C --- see inheritance and operator overloading, just to name two.
The books you have are excellent ways to learn the language, and this one complements them in that it lists common practices around, for example, error handling, and other common topics. It shows different approaches and mentions practices from real-world open-source C projects that follow them.
It seems like a good book to continue exploring C after learning the language.
I worked with Objective-C in the late 90s and again in the 2010s, which is basically C with funky object stuff.
I don't miss it at all. C is very low level and so easy to write bad code in if you don't have solid discipline, the language doesn't help at all, which was not really a design decision back then. The first C compiler we used didn't even support prototypes.
I exclusively use Swift now.
Surely you mean C89, where functions have some type safety but C’s variable declaration syntax remains a horrible inelegant kludge?
Have you written much code in Swift?
The speaker discourages C for new projects, but that says more about the problem domains they work in than C itself. C is what it is because the hardware and assembly language are what they are. Folks who want a safer C should design a new hardware architecture with a "safe" assembly language and a new low-level language that targets it.
It's a massive red flag that they don't know enough to be useful.
C is great for the things C is great for, however small that range may or may not be now and in the future.
Any other stance is reductive and misleading.
It's really not, though. What C is an abstraction of is computer architecture as it existed by the late 1960s.
Would that be LLVM's IR or MLIR (https://mlir.llvm.org)?
I assume you're being facetious with the "recently came across", since scipy is so common, but I will add that nearly every math-intense library is a clever wrapper for some Fortran code.
I would be perfectly happy to see many hardened C libraries become the foundation of the next gen systems/ embedded languages. It does bother me slightly when we abandon the past entirely and attempt to "rewrite it in X"
But just like Fortran is still used for nearly every math-intense library, mostly invisible for most of the users, I suspect that C will still be around in 50 years from now.
I agree, with his observation that C should be no longer your language of choice for new projects. I personally still prefer using C/C++ for my private software projects, simply because it is the language I am most fluent in. This year I used it for AoC.
Not exclusively in C, not anymore: https://docs.kernel.org/rust/index.html
It might take another decade for a C-free build to be possible, though.
SciPy is a highly optimized library and Fortran is faster than C for some tasks:
Unfortunately it's an industry with a lot of stubborn old people so I don't see any major changes happening until they've retired but I'm willing to bet that async is going to revolutionize embedded development. Being able to await interrupts and doing efficient cooperative scheduling while writing straight forward code is a massive QoL improvement which is what embassy is enabling: https://embassy.dev/
Unfortunately Ada is held back by a genuine lack of awareness and some old misinformation baggage.
There are surelly other factors that weight in using C, but not for lack of options (in many cases).
Or maybe they will, given how much consultants in those languages happen to be paid, as no one else wants to touch them.
I do dream about that. Just being able to tag along while some programmers learn their Xth framework as a language.
Maybe someday I might concede and move on from C89 to C99.
If anything, C may still be going strong for another 20 to 30 years.
One reason for C to disappear completely would be if computer architectures would change so much that current programming languages no longer even map to those new architectures (e.g. all the existing programming languages would need to be dumped anyway).
> The Lindy effect (also known as Lindy's Law[1]) is a theorized phenomenon by which the future life expectancy of some non-perishable things, like a technology or an idea, is proportional to their current age. Thus, the Lindy effect proposes the longer a period something has survived to exist or be used in the present, the longer its remaining life expectancy.
C does have a similar kind of niche at first glance: systems programming is of course conservative, rewriting everything is unlikely, and of course, C is the language used for ABI. Except on closer inspection, that moat is remarkably shallow. Being the language of ABI means that every competitor language has some way to speak C guaranteed, so the friction of rewriting systems software Ship-of-Theseus-style is much lower (though still nonzero). Systems software is rewritten from scratch on a much higher cadence: in the last 20 years or so, most of the userspace system glue for Linux has been replaced (e.g., systemd, iproute2, pulseaudio, wayland). And we've learned over the past few decades that there's no practical way to fix C's fundamental unsafety issues with software engineering practices, and C's committee is too conservative to consider retrofitting the necessary features to be able to fix unsafety at a language level (to say nothing of getting people to use it).
There is already a small clutch of languages that can serve C's niches that don't have the same fundamental unsafety issues, and right now, we're sort of at an experimental stage of system software trying them out. It's not unreasonable to believe that within a decade or so, one or more of these languages would be considered a standard, safe choice for implementing new systems software--and the use of C in new projects will start dropping. At some point, the proliferation of non-C systems projects will make people point out that having these components talk through C's ABI is too limited in functionality, and a system will change its ABI from C to some other language. And once it is no longer the language of ABI, C will lack its moat that keeps it alive, and it will start dying, though its death will be a slow, agonizing death.
Alongside RAII for resource management.
Namely, if it has to be "replaced", that would be with something with a much simpler syntax, which will require a bit more of finger power. We don't want to find ourself locked-in by very few compiler vendors (open source or not), that only because it is not reasonable to code a real-life alternative with a small team of averagely skilled devs in a reasonable amount of time.
This language should build on C though: no enum/typedef/_generic/switch/etc, only 1 loop keyword (loop{}) only explicit sized types, no integer promotion, no implicit casts (except maybe void* pointers but number literal casts should be) but explicit casts (compile-time and runtime, without that horrible c++ syntax), explicit compile-time const (we have only runtime consts which could be optimized as compile-time consts), enforce extern for functions (and don't try to put the binary format, elf/coff/etc, semantics into the language syntax or worse, the OS interface semantics), etc.
With enough discipline (and compiler warnings), we could get close to such language.
I did not check the latest and greatest rust syntax, but is what's above its explicit goals?
That said, I am a "everything in 64bits RISC-V assembly with x86_64/arm64 legacy ports kind of guy"... if RISC-V is successful (I wish). We could think of high-level language interpreters (coded in assembly, for instance a RISC-V coded python/lua/javascript/etc interpreters).
The language has a few irritating historical artefacts and the stdlib API is completely outdated and full of bad design, but there it is still versatile enough for my needs.
It is also completely unnecessary on Linux. I switched to freestanding C and discovered it was a much better language. Made programming fun again. All I needed was one system call function and some entry point code.
It's gotten to the point that it bothers me that gcc could potentially generate calls to mem* functions even in freestanding mode.
https://www.schneier.com/blog/archives/2007/09/the_multics_o...
"Multics B2 Security Evaluation"
https://multicians.org/b2.html
But naturally ignoring it was more fun,
> Although we entertained occasional thoughts about implementing one of the major languages of the time like Fortran, PL/I, or Algol 68, such a project seemed hopelessly large for our resources: much simpler and smaller tools were called for. All these languages influenced our work, but it was more fun to do things on our own.
>"if you want to write new program in C now think long and hard and pick something else"
I would not use plain C to write enterprise backend servers. I happily use modern C++ for that.
For some very low power microcontrollers however I absolutely would. Amount of high quality free tooling and libraries beats everything else.
From a practical point of view: I've written enough firmware for very lowly microcontrollers like AT90USB1286. Runs like a charm (oldest for 10 years already), did not not require even single bug related update and zero complaints from customers. Changing the language in this particular case would bring no benefits but extra expense.
I tend to think unless perform/$ is really important one should use a managed language for that, that isn't Javascript.
But yeah, not really sure what some other language would buy me in the small embedded space that earns me my beer money. I recently had an issue where the corporate spyware was convinced make/gcc were up to no good resulting in minute and a half compile times instead of the usual 10 seconds. I spent a bunch of time with IT getting that fixed. Well that's the build time I'd get with Rust. So Rust is a big nope. C++ is not that slow but still slow. And C++ without malloc is well who are we trying to kid here.
For my particular project managed language would simply not work. Way too slow. Besides the code base is relatively small and higher level language would not offer any compelling benefits.
>"minute and a half compile times"
Just checked. My particular project compiles under 1 second using Atmel Studio 7.
You simply have to build or use a different framework offering similar or better APIs.
It feels like it's the best way I want to do this. That way, a C compiler can do a lot of work I really don't want to do, C already has backends, optimizers, etc etc.
All I want is a C-like language with native strings, hash map and list, tuples python indentation, vector math, and nothing else, and make it as simple as possible.
I'm a bit tired of new language trying to do new things, I just want something less verbose than C, but not as powerful as C++, with the feeling of python.
They're great languages, but they're not what I want.
It's close to what I want to do, except it doesn't have python indentation, and it doesn't have tuples.
Even Petzold embraced C++, even if superficially,
"This third edition has several changes. First, all programs are now compilable with either the Microsoft or the Borland compiler. All make files are generic and use environment variables for compiler flags, link libraries, and so forth. Second, all programs are now compilable in C++ mode. Although I don’t use any C++ specific features, compiling first in C++ mode is helpful if C++ features are to be added later to the code"
-- https://archive.org/details/programming-windows-31-3rd-ed/pa...
Veiled insult noted ;)
I used both, but TurboC was a real game changer for me. I came from the ST using MWC and ended up in very unfamiliar territory on Windows, Borland TurboC made all the difference for me. It allowed me to be productive on an unfamiliar platform, compiles were absolutely lightning fast compared to anything the competition put out and was rock solid.
Edit: I just realized I still have ctrl-f9 more or less in my muscle memory. It's been decades...
Happy New Year by the way, if you are still up and reading this!
C without undefined behaviors is not C anymore by the way. It would be something else.
It is not hard to say what is unique about C: it and Forth are the only high level languages with seamless access to memory. If other languages offer it at all, like PEEK and POKE and Basic, it is far more awkward and interrupts your flow. That might be a good thing - the ESPOL compiler mentioned in the talk would print a big fat warning "YOU MUST KNOW WHAT YOU ARE DOING!" after any line in your code doing C-like tricks.
He goes on to list the following options (and says C++ does not count), but we'll only know far in the future which would have been the right pick:
- Rust
- Go
- Zig
- V
- Nim
- Swift
- ...
So while a security conscious group can write C++ code that takes advantage of those features, other group can basically compile C++ code that is hardly any different from C.
So it is a better option than raw C, if it is the only viable alternative (like in HPC), but for security conscious scenarios one of the others is a better answer, if available.
Nothing compares to the raw power and control we get with C.
Around '97-98 Java was all the rage. Then Bill Gates did his internet pivot and we had .NET arriving in the '00s. The allure of being able to program in any framework language and interoperate looked like a good thing.
Over the last 20+ years I had been in the .NET world and just this year I went back to writing in C and it all came back. It is quite refreshing to be completely responsible for every aspect of your code's working. While it is sometimes tedious, nothing beats the power and control of working close to the machine abstraction.
Just my 2cents.