There's fair amount added to the core since C89, actually... And if you include the library changes, game over! I had no idea how much had been added.
More challenging is to find what's been subtracted.
This no longer defaults to int:
static i;
And gets() is toast.
Anyone know any others?
But yes, the code is also quite different than in K&R which is relatively terse. See for example this comment in K&R about strcpy on print page 105 (page 119 of the PDF)[1], where after showing two versions of strcpy that are pretty readable and easy to follow, the book says:
> In practice, strcpy would not be written as we showed it above. Experienced C programmers would prefer
void strcpy(char *s, char *t)
{
while ((*s++ = *t++) != '\0')
;
}
Followed by a paragraph saying the condition could be simplified, and that> the function would likely be written as
void strcpy(char *s, char *t)
{
while (*s++ = *t++)
;
}
Make of that what you will :-)All those code samples will crash and burn if s and t point to the wrong locations, t happens to point to a string without a null terminator, or s points to a buffer not big enough to handle the string pointed by t.
This is true for all uses of pointers in C. The only validation you can do is whether a pointer is null. Apart from that you can never know that a pointer points to a non-wrong location. And still experienced C programmers seem to be OK with using pointers.
But even then, most experienced C programmers don't care about using them anyway, that is why Apple, Oracle, Microsoft, ARM, Google, Cambridge university are all leading efforts for hardware memory tagging.
So it won't matter how much they care, as the OS will kill their beloved application when pointers get misused.
A scenario already made reality in platforms like Solaris SPARC.
Are outside the scope of the C language. But if you allow these special APIs, you can use them to implement a safe strcpy. Either way your point from above is still invalid.
while (*s++ = *t++);
is the type of thing seemingly designed to reach through history to make a modern programmer spit out their tea — but I also can’t help but feel that it’s a very direct “C machine” representation of the semantics of a processor string instruction, ala x86’s REPNZ MOVSB.I'd have a hard time calling the way they designed _Generic "a nice thing" :-)
Edit:
https://www.stroustrup.com/bs_faq.html#C-is-subset
>Please note that "C" in the paragraphs above refers to Classic C and C89. C++ is not a descendant of C99; C++ and C99 are siblings.