6 ms·
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 trai
by tba 15y ago
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 is a fundamental concept of C strings; there's no reason to shield C students from it.
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.
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.
- angersock 15y agoIt's a nice strawman, right? Especially when he points out that the original code, in context, is perfectly fine. His later complaint about the assignment-in-if statement is certainly something shared by modern C programmers (see compiler warnings about same), but it perfectly fits the original style and accomplishes its task. His criticisms seem to be rooted so far in stylistic issues and in taking the code out of context (design context, usage guarantees, etc.). Then again, how are you to nerdbait while still being fair to original sources?
- zedshaw 15y agoMy criticisms are only partially stylistic, but also that people copy this code to other situations and it breaks. So, I'm showing them why it only works in that one specific context and how to break the code.
- angersock 15y agoIf I can make a suggestion, then. I apologize if you've already covered this elsewhere in your book, but: Please encourage the use of the "restrict" keyword to encourage proper aliasing optimization by compilers. Also, would it be worth considering, perhaps in a chapter on how-to-deal-with-C-style-strings-if-you-must, including a section on writing compiler-independent macros to emulate safer calls like the str*_s variants in VS. These functions are usually slightly-different in incantation across VS and GCC, so it might be helpful to abstract them. It also is a relatively simple exercise in preprocessor macros with a clear benefit.
- mechanical_fish 15y agoThe 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 good C code just doesn't use C style strings. In later exercises we'll actually learn how to avoid C strings completely. This is the author's opinion, of course – it's from a book, that should go without saying – but it's not as if the idea of avoiding C strings in general, and "strcpy" in particular, is an oddball or unique point of view. See e.g.: http://stackoverflow.com/questions/610238/c-strcpy-evil http://stackoverflow.com/questions/610238/c-strcpy-evil
- peapicker 15y ago"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.
- listic 15y agoThe approach looks similar to the one in "JavaScript: the good parts" I am worried about the same while reading it: ok, here's the right way to do e.g. inheritance, but how do they do it in real world?
- mechanical_fish 15y agoThis chapter is explicitly teaching people what the author's idea of bad C code is: It has them read some, then tells them specifically what the gotchas are, then asks them to code up test cases for the flaws and run them through Valgrind. 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?
- geophile 15y agoHuh? 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 http://linux.die.net/man/3/strcpy. It sounds like you are talking about strncpy or memcpy.
- blix 15y agoI'm confused by your comment. strcpy assumes that the string to be copied ends with a NUL. The case described in the link violated that assumption and caused a segfault.
- marshray 15y agoTo be pedantic, it's not that strcpy is making assumptions. Its interface is defined such that it is explicitly invalid to pass it some other garbage.
- zedshaw 15y agoTo be both pedantic and correct, there is no way to define a C function to restrict a string input so that it is correctly terminated. So no, it's at best documented that you shouldn't do that and definitely doesn't prevent you from doing this.
- ec429 15y agoTo be still more pedantic, there are two kinds of definition of an interface: definition-within-the-type-system and definition-within-the-documentation. The string library is specified in the ISO C standard (I use C99, but you can be all hip and C11 if you want), and passing an unterminated string to strcpy is a constraint violation. 7.1.1 A string is a contiguous sequence of characters terminated by and including the first null character. 7.21.2.3.2 The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1. Therefore, code which passes an unterminated string to strcpy is not conforming code (because s2 does not point to a "string" as C99 defines it). Of course, you should use strncpy anyway. But that's not the point. /me spends too much time in comp.lang.c :S
- deleted 15y ago[deleted]
- X-Istence 15y agoThe other time that there will be an issue is when your to is shorter than your from...
- zedshaw 15y ago> but no function with that signature could possibly work in this case. This is the source of the bugs in C. People write functions that only work given all calls to them are never changed, which is absurd. Good modern C code involves trying to protect against bad usage and adding defensive checks. So yes, the built-in strcpy is crap which is why most competent C doesn't use it except in a few rare cases where it's required. And this does demonstrate actual bugs in the code. I wrote a test case that causes it, which incidentally is a common bug in C code called a buffer overflow. It's because of code examples like this that get copied to other situations that we have these defects.
- tptacek 15y agoHigh level string libraries are a win. But you may be overstating your case a bit. From my codebase/third-party directory on my laptop (a bit random, I admit), from those projects I'd consider "competent C" (ie, not OpenSSL or MRI ruby): * dovecot uses ASCIIZ strings and libc string functions * redis uses ASCIIZ strings and libc string functions * nginx uses a high-level buffered string library * lcamtuf's skipfish scanner uses ASCIIZ strings and libc string functions * libevent uses ASCIIZ strings and libc string functions * qmail uses djb's string library * memcached uses ASCIIZ strings and libc string functions It's probably good to be comfortable with both approaches. I don't know that you actually made this claim, but you seem to have given people here the impression that you believe functions that work with ASCIIZ strings should be bulletproofed to handle non-ASCIIZ inputs. I couldn't agree with that argument, especially as an argument about K&R's code being rusty. People here are jumpy though (they're commenting, like me, mostly because they're bored). Looking forward to more examples from the book.
- aaronblohowiak 15y agoRedis strings are actually length prefixed null terminated strings
- tptacek 15y agoThe string data type in the db? Because Redis itself uses char-stars all over the place, with the libc string functions.