Live data from Hacker News

Deconstructing "K&R C"

c.learncodethehardway.org

91–100 of 136 posts

Re: Deconstructing "K&R C"

#91
post #88
post #61

Earlier quoted context omitted.

> 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 r…

High 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 s…

Redis strings are actually length prefixed null terminated strings

Re: Deconstructing "K&R C"

#92
post #69
post #57

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. 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.

The problem is in the word "expects". This function expects certain things but doesn't assert that they're happening. Because of this you get bugs when you try to use that function in other code, which is what beginners do. And yes, the solution is to require a size with every string buffer, which is what I do nearly all the time now. But, the best way to learn why that's solution is to try to hack something with thi…

I think the core issue here is how C style strings are implemented. Personally, I much prefer if C strings were , but what I was going after is that it's not K&R specific, it's a C design "mistake".

Re: Deconstructing "K&R C"

#93
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 - http://go-lang.cat-v.org/pure-go-libs, when Go was publicly released?

That is, stop writing books about C and start creating new languages.

Re: Deconstructing "K&R C"

#94
post #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) /…

Because it's the style I use, and because I don't need to bug-check the indented code to make sure it's braced correctly, I find this easiest 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); }

By far.

Re: Deconstructing "K&R C"

#95

Earlier 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.

> unprepared for C in the Real World

Oh please. Most C in the "Real World" is utter crap. It doesn't mean there is no place for books teaching "alternative" approaches.

Re: Deconstructing "K&R C"

#96
post #83

Earlier quoted context omitted.

To 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.

To 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.

To 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

Re: Deconstructing "K&R C"

#97
Myself, I learned from K&R, and I thought it was great at the time, now I'm less sure of this.

I've heard that "A Book on C" is supposed to be a much better book for learning C

Re: Deconstructing "K&R C"

#98

> 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.

I'm currently experimenting with a hybrid of this and K&R style, that would look like this:

  while ((len = getline(line, MAXLINE)) > 0)
      if (len > max) {
          max = len;
          copy(longest, line);
          }
    
      if (max > 0) /* there was a line */
          printf("%s", longest);
So far I'm finding that it gives good readability, doesn't waste too many lines on braces, and doesn't run into many issues of accidentally leaving braces out.

I started it after having started writing lisp and python, and I'm getting used to just ignoring the braces and going by indentation, which this style emphasises.

Re: Deconstructing "K&R C"

#99

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 - http://go-lang.cat-v.org/pure-go-libs , when Go was publicly released? Th…

A lot of C lovers I see.

Re: Deconstructing "K&R C"

#100
post #88

Earlier quoted context omitted.

High 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 s…

Redis strings are actually length prefixed null terminated strings

The string data type in the db? Because Redis itself uses char-stars all over the place, with the libc string functions.
Post reply on HN