Opinion alert: it’s time to start moving past C for programming software
There are a lot of things that C does well and has its strengths in; it’s fast, standard, simple, and even flexible in some senses of the word. However, one thing it does not do well is act as a platform for designing software. It is slow to develop. If you aren’t writing C 100% of the time, you’re probably going to be more prone to making errors that the compiler simply ignores because “the programmer knows best”. It can be difficult for people to pick up if they don’t have any experience with lower level programming. This is not to say C is a bad language, nor is it to say that C is obsolete. C excels as a machine-level language; that is to say, it is great for controlling hardware. I’ve always thought of C as a shorthand for assembly. It sets up the stack for you, it manages variables and their offsets, it handles the measures of data structures (specifically structs/unions), standardizes method calls, and (arguably most importantly) can compile code down to be run on the very most barebones of nearly any computer.
C exists so we aren’t writing assembly code 100% of the time when we’re writing software that operates very closely to/on the hardware (OS kernels, device drivers), but I believe it only exists as a replacement for 99% of the assembly we’d normally have to write. In constrast, it does not exist as a programming language to do software design and application design in. C was written so that you don’t have to worry about messing up your offset for the second argument on the call stack, or forgetting to push a callee-save register; rather, you are able to worry about the real programming problems and not have to slog through hidden architecture-specific problems.
Just like C, languages like Java and Python and (any other modern language here) were written so we don’t have to worry about mystery segmentation faults, linker errors, array bounds issues, and memory leaks. They abstracted the complicated, nonintuitive things about C and let the compiler/interpreter handle them so you could focus on the real problems.
Obviously, if performance is utterly critical, or you need absolute fine-grained control over the software you are writing, or you’re writing for some microcontroller where it’s either that or assembly: C is perfect and the wise choice. Just… don’t go out and write an IRC client or a web browser or shell or email client or whatever in C. It’s not a language designed for software design, it’s a language designed for being a shorthand for machine code.