The safer the C code, the more horrible it starts looking though... e.g.

    my_func(char msg[static 1])

I don't understand why people think this is safer, it's the complete opposite.

With that `char msg[static 1]` you're telling the compiler that `msg` can't possibly be NULL, which means it will optimize away any NULL check you put in the function. But it will still happily call it with a pointer that could be NULL, with no warnings whatsoever.

The end result is that with an "unsafe" `char *msg`, you can at least handle the case of `msg` being NULL. With the "safe" `char msg[static 1]` there's nothing you can do -- if you receive NULL, you're screwed, no way of guarding against it.

For a demonstration, see[1]. Both gcc and clang are passed `-Wall -Wextra`. Note that the NULL check is removed in the "safe" version (check the assembly). See also the gcc warning about the "useless" NULL check ("'nonnull' argument 'p' compared to NULL"), and worse, the lack of warnings in clang. And finally, note that neither gcc or clang warn about the call to the "safe" function with a pointer that could be NULL.

[1] https://godbolt.org/z/qz6cYPY73

> I don't understand why people think this is safer, it's the complete opposite.

Yup, and I don't even need to check your godbolt link - I've had this happen to me once. It's the implicit casting that makes it a problem. You cannot even typedef it away as a new type (the casting still happens).

The real solution is to create and use opaque types. In this case, wrapping the `char[1]` in a struct would almost certainly generate compilation errors if any caller passed the wrong thing in the `char[1]` field.

Compared to other languages, this is still nice.

It is - like everything else - nice because you, me and lots of others are used to it. But I remember starting out with C and thinking 'holy crap, this is ugly'. After 40+ years looking at a particular language it no longer looks ugly simply because of familiarity. But to a newcomer C would still look quite strange and intimidating.

And this goes for almost all programming languages. Each and every one of them has warts and issues with syntax and expressiveness. That holds true even for the most advanced languages in the field, Haskell, Erlang, Lisp and more so for languages that were originally designed for 'readability'. Programming is by its very nature more akin to solving a puzzle than to describing something. The puzzle is to how to get the machine to do something, to do it correctly, to do it safely and to do it efficiently, and all of those while satisfying the constraint of how much time you are prepared (or allowed) to spend on it. Picking the 'right' language will always be a compromise on some of these, there is no programming language that is perfect (or even just 'the best' or 'suitable') for all tasks, and there are no programming languages that are better than any other for any subset of all tasks until 'tasks' is a very low number.

I agree that the first reaction usually is only about what one is used to. I have seen this many times. Still, of course, not all syntax is equally good.

For example, the problem with Vec<Vec<T>> for a 2D array is not that one is not used to it, but that the syntax is just badly designed. Not that C would not have problematic syntax, but I still think it is fairly good in comparison.

C has one massive advantage over many other languages: it is just a slight level above assembler and it is just about as minimal as a language can be. It doesn't force you into an eco-system, plays nice with lots of other tools and languages and gets out of the way. 'modern' languages, such as Java, Rust, Python, Javascript (Node) and so on all require you to buy in to the whole menu, they're not 'just a language' (even if some of them started out like that).

Not forcing you into an eco-system is what makes C special, unique and powerful, and this aspect is not well understood by most critics. Stephen Kell wrote a great essay about it.

Meanwhile, in Modula-2 from 1978, that would be

    PROCEDURE my_func(msg: ARRAY OF CHAR);
Now you can use LOW() and HIGH() to get the lower and upper bounds, and naturally bounds checked unless you disabled them, locally or globaly.

This should not be downvoted, it is both factually correct and a perfect illustration of these problems already being solved and ages ago at that.

It is as if just pointing this out already antagonizes people.

A certain group of people likes to pretend before C there were no other systems programming languages, other than BCPL.

Ignoring what happened since 1958 (JOVIAL being a first attempt), and thus all its failings are excused because it was discovering the world.

I think the main reason you see this happening over and over again is because we're teaching this whole discipline wrong. By 1960 most of the problems in software development were known and had one or more solutions. Knuth spent decades just cataloging what was mostly already known (and moved the field forward in quite a few occasions as well).

And yet, you can't go a day without someone declaring that now is the time to do it right, this time it will be different. And then they proceed to do one thing after another for which the outcome is already known, just not to them. I think the best way to teach would be to start off with a fairly detailed history of what had gone before, just to give people a map and some basic awareness of the degree to which things have already been done, rather than to find new and interesting ways to shoot themselves in the foot (again).

Unlike actual engineering, software "engineering" as a field has decided to reinvent itself every generation - worse, every turn of the trends, even every project and person. Majority of the practitioners are in it for superficial reasons, unaware of its rich history and culture.

With ignorance comes arrogance of an individualist intellectual, thinking their unique revolutionary contribution will wow the public and move the field forward. Except inevitably they're not only reinventing the wheel but the entire automobile, without knowing basic principles and the work of predecessors. It has a lot in common with modern art.

> we're teaching this whole discipline wrong

I sometimes think languages after C, like C++ and Java, were misguided in some ways. Sure they provided business value, brought new ideas, and the software worked - but their popularity came at a cost of leaving countless great thoughts behind in history, and resulted in a poverty of software culture, education and imagination.

There are optimistic signs of people returning to the roots, re-learning the lessons and re-discovering ideas. I think many are coming to realize the need for a reformation of sorts.

[deleted]