I'm confused. What is the "defect" in K&R's "copy(char to[], char from[])" function? 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. The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Null-termination…
Huh? My C programming is in the distant past, so I might be forgetting. But strcpy does assume a terminal zero, doesn't it? E.g., http://linux.die.net/man/3/strcpy . It sounds like you are talking about strncpy or memcpy.
Deconstructing "K&R C"
31–40 of 136 posts
Re: Deconstructing "K&R C"
#32Earlier quoted context omitted.
The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Yes. From the linked chapter: we avoided classic style C strings in this book From an earlier chapter on strings: The source of almost all bugs in C come from forgetting to have enough space, or forgetting to put a '\0' at the end of a string. In fact it's so common and hard to get right that the majority of…
"the majority of good C code just doesn't use C style strings..." Nice. In the 23 years I have worked on C language products, I've never worked on "good C code" by this definition. The cool thing about this guys book, I guess, is that by avoiding all the things about the language he doesn't like, any reader will be wholly unprepared for C in the Real World after this book.
Re: Deconstructing "K&R C"
#33> Braces Are Free, Use Them I disagree. Braces have a cognitive load, particularly if they're given whole lines to themselves. Which is easier to read, while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); or while ((len = getline(line, MAXLINE)) > 0) { if (len > max) { max = len; copy(longest, line); } } if (max > 0) /…
while ((len = getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) { /* there was a line */
printf("%s", longest);
}Re: Deconstructing "K&R C"
#34Earlier quoted context omitted.
One problem with it is that on most compilers if you compile with optimizations it will remove the assertion. Now the code is no longer guarded against malloc failures and will just segfault. If the intent is to teach people how to handle malloc failures gracefully, it's not that great of an example.
Why do you think the compiler with optimizations will remove the assertion? The compiler will realise that: assert(assert(line != NULL && longest != NULL && "memory error"); Is equivalent to: assert(line != NULL && longest != NULL); But there doesn't seem anything wrong with that.
#ifdef NDEBUG
#define assert(e) ((void)0)
#else
#define assert(e) \
((void) ((e) ? 0 : __assert (#e, __FILE__, __LINE__)))
#define __assert(e, file, line) \
((void)printf ("%s:%u: failed assertion `%s'\n", file, line, e), abort())
So, if NDEBUG ("no debug") is defined, which it is if optimizations are turned on, asserts become a no-op.Re: Deconstructing "K&R C"
#35Earlier quoted context omitted.
The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Yes. From the linked chapter: we avoided classic style C strings in this book From an earlier chapter on strings: The source of almost all bugs in C come from forgetting to have enough space, or forgetting to put a '\0' at the end of a string. In fact it's so common and hard to get right that the majority of…
"the majority of good C code just doesn't use C style strings..." Nice. In the 23 years I have worked on C language products, I've never worked on "good C code" by this definition. The cool thing about this guys book, I guess, is that by avoiding all the things about the language he doesn't like, any reader will be wholly unprepared for C in the Real World after this book.
Where's the "avoiding" here?
And which of the skills being exercised - imagining what kinds of bad things could happen, writing executable test cases, detecting segfaults - are not useful in the real world?
Re: Deconstructing "K&R C"
#36> Braces Are Free, Use Them I disagree. Braces have a cognitive load, particularly if they're given whole lines to themselves. Which is easier to read, while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); or while ((len = getline(line, MAXLINE)) > 0) { if (len > max) { max = len; copy(longest, line); } } if (max > 0) /…
Always using braces, and giving them their own lines makes nesting as unambiguous as possible and the extra white space reduces density making foreign code easier to digest.
Re: Deconstructing "K&R C"
#37I'm confused. What is the "defect" in K&R's "copy(char to[], char from[])" function? 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. The built-in "strcpy" function has the exact same limitation. Does the author have a problem with it as well? Null-termination…
Re: Deconstructing "K&R C"
#38Stack 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).
Re: Deconstructing "K&R C"
#39> Braces Are Free, Use Them I disagree. Braces have a cognitive load, particularly if they're given whole lines to themselves. Which is easier to read, while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); or while ((len = getline(line, MAXLINE)) > 0) { if (len > max) { max = len; copy(longest, line); } } if (max > 0) /…
I'm probably the last person in the world to prefer: while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); I fear this may be literally true: this brace style is called Whitesmith's, and I was reporting bugs to the cc-mode indenter for emacs a while ago. BSD/Allman and K&R styles never made sense to me.
Re: Deconstructing "K&R C"
#40Earlier quoted context omitted.
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? We are getting separated from that kind of behavior. Nowadays the language is generally expected to protect you from yourself.
No, C is specifically for situations where you don't want the language to "protect you from yourself". E.g. systems programming where little or no runtime performance will be sacrificed to enable imperfect code to be safe.