I'm confused. What is the "defect" in K&R's "copy(char to[], char from[])" function?<p>The author notes that "the second this function is called...without a trailing '\0' character, then you'll hit difficult to debug errors", but no function with that signature could possibly work in this case.<p>The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Null-termination is a fundamental concept of C strings; there's no reason to shield C students from it.<p>The other example of "bugs and bad style" in this "destruction" of K&R C is a minor complaint about not using an optional set of braces.<p>I hope the remainder of the [incomplete] chapter demonstrates some actual bugs in the book's code, because it currently doesn't live up to the first paragraph's bluster.
I don't see what the big deal is here. He throws inputs at a function not meant to handle them and gets a segfault. Isn't this more-or-less expected from all C functions?<p>On careful examination of his example code, you can see that there's no attempt to terminate the buffer (though he misidentifies it as an "off by one" error). Throwing arbitrary buffers into functions meant for null-terminate strings will cause errors everywhere, not just in K&R example code. In the next chapter, does he use strcpy in the same example and use that error to say that we should deprecate the entire standard library?<p>On a more nit-picky note, the 'triple-equality trick' the author derides is a common C idiom and one every C programmer should be familiar with. Perhaps it doesn't belong in the first chapter, but it definitely belongs in any C manual.
> Braces Are Free, Use Them<p>I disagree. Braces have a cognitive load, particularly if they're given whole lines to themselves. Which is easier to read,<p><pre><code> while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
</code></pre>
or<p><pre><code> while ((len = getline(line, MAXLINE)) > 0)
{
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0) /* there was a line */
{
printf("%s", longest);
}
</code></pre>
? Personally, I'd probably write it<p><pre><code> while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) printf("%s", longest);
</code></pre>
. Consistent structural indenting makes it easy to see the boundaries of the control structures.
I don't see his point, really. Yes, C doesn't have a statically testable string type. And yes, the convention is that a C "string" is just an array of character data with a trailing NUL-Byte. He constructs an array without a trailing NUL-Byte - so that's not a string, but an array of characters.<p>The fact that copy() now happily runs through memory is the expected result of the bug in the calling code. No, it's not useful. Yes, there are problems with the whole approach of using a terminating value - but this doesn't seem to be his point (otherwise he would also have mentioned the linear runtime complexity of strlen() and the problems that arise when a string itself contains a NUL-byte, I suppose).<p>Now, what is his point? This is chapter 55 [!] in a book called "Learn C The Hard Way" and the author complains about well-know problems with the standard-lib string convention, optional braces, and the common C idiom of doing assignment and value-testing at the same time, _and_ calls all of this 'Deconstructing "K&R C"'?<p>Maybe a "What I personally don't like about C" would have been a better title. The K&R examples are flawless. The language and stdlib are not. That's well-known. What is new?
It's worth noting that this isn't a standalone article; it's lesson 55 in "Learn C the Hard Way". In other words, this isn't meant to be a thorough critique. It's just one lesson of many.
Guys, no need to jump all over this, clean code and defensive programming are solid practices to advocate. "That's just the way we do C" isn't really a good defense to someone trying to point out the warts in the way we do C, even if it did come from K&R.<p>Its easy to point to this for not sufficiently proving its argument, but its a work in progress, you're not the target audience, and finally, some of the shit in K&R seriously would not pass a code review here, and probably wouldn't where you work either.
I think people are misunderstanding this; it's pedagogical. From the link:<p>'I want to use it as an exercise for you in finding hacks, attacks, defects, and bugs by going through "K&R C" to break all the code...When you are done doing this, you will have a finely honed eye for defect.'<p>He's trying to train his readers to think about places code can break.
"Before the switch to heap memory, this program probably ran just fine because the stack allocated memory will probably have a '\0' character at the end on accident."<p>Stack memory is not preinitialized to '0' either so using stack memory would show this 'defect' as well (as others have pointed out this is a defect in the calling code, not in copy).
To be honest, I was never that impressed with the K&R book as an introduction. Coming from a higher level language (Pascal) in college after several years back down to C was painful. K&R (borrowed from a classmate) presumed too much obviousness in what assembly language constructs were being abbreviated by a given piece of C code, and what the other pieces of C code around the example to be explained did.<p>Later in the semester I picked up a copy of the first edition of this book:<p><a href="http://books.google.com/books/about/C_an_advanced_introduction.html?id=QtjsnjT2BjwC" rel="nofollow">http://books.google.com/books/about/C_an_advanced_introducti...</a><p>This book did a much better job of explaining what the hell was going on, particularly in regards to managing memory / strings / arrays / (C) pointers and understanding their placement.<p>Sure, Pascal had pointers, when you asked for them :-)<p>Yeah, throw the K&R book at newbs you hate.
Myself, I learned from K&R, and I thought it was great at the time, now I'm less sure of this.<p>I've heard that "A Book on C" is supposed to be a much better book for learning C
Not only the book "needs to be taken down from its pedestal" but it's time for the C language itself to go. It was fine language at the time (better than assembly I guess). No more. Not in the 21st century. The most common excuse for sticking with C is efficiency - I pity those who still believe so. Another excuse is extended set of libraries - <a href="http://go-lang.cat-v.org/pure-go-libs" rel="nofollow">http://go-lang.cat-v.org/pure-go-libs</a>, when Go was publicly released?<p>That is, stop writing books about C and start creating new languages.
The function copy expects a C style string but he pass a buffer to some data. If you pass it the proper argument you'll get a proper result, it's that simple.<p>I see the complaint is more about C style strings in general because it's easy to corrupt them by overwriting NULL at the end rather than a complaint about "K&R C" book. I don't get why he decided to put it under this title.
I'm sure I'll be downvoted, but C is not Java.<p>From what I can tell, the "it's time for C to go" comes from a generation raised on Java.<p>C still has its place.
Kind-of a long-winded way to point out the (very well known) fact that passing non-terminated strings to functions that expect terminated strings is fraught with danger, isn't it?