Live data from Hacker News

Deconstructing K&R C Is Dead (2015)

c.learncodethehardway.org

91–100 of 190 posts

Re: Deconstructing K&R C Is Dead (2015)

#91
Damnit, I was tricked into reading something by professional troll Zed Shaw. The hypocrisy of him complaining about "the dark side of programming" is hilarious consdering he is a very good example of that. His style of debate is to insult and call people names who have offered non-judgemental and constructive criticism and I'm sure nothing I'm saying is news to anyone who has a passing familiarty with him.

Re: Deconstructing K&R C Is Dead (2015)

#92
I looked at Zed's books but didn't find them either containing much of useful material, or written well enough to be worth reading. Granted, I'm not a novice to subjects he writes about. But still, I find it peculiar that his high opinion of his works seems to be rather detached from reality. The books are written in a simplistic and sometimes demeaning style and it's obvious that many people will not like it. But when someone writes an honest review, he seems to get too upset about it. While he obviously likes to critique other peoples' works (such as K&R), he's very sensitive to critique of his own books. Zed thinks that it's acceptable to insult the reviewer (Tim Hentenaar) in response. Reading his response made me cringe. Insulting reviewers is just not what respectable authors do.

Re: Deconstructing K&R C Is Dead (2015)

#93

Earlier quoted context omitted.

There are so many to choose from. Here is one I just thought up: void free_circularly_linked_list(struct node *head) { struct node *tmp = head; do { struct node *next = tmp->next; free(tmp); tmp = next; } while (tmp != head); } Can you spot the undefined behavior?

The `tmp != head` comparion is UB because `head` is a dangling pointer after the first loop iteration, right?

Yep! To do this properly requires something more like:

    void free_circularly_linked_list(struct node *head) {
      struct node *tmp = head->next;
      while (1) {
        if (tmp == head) {
          /* Has to be a separate case since even assigning
           * a dangling pointer is UB I believe? */
          free(tmp);
          break;
        } else {
          struct node *next = tmp->next;
          free(tmp);
          tmp = next;
        }
      }
    }

Re: Deconstructing K&R C Is Dead (2015)

#94
post #54
post #6

Low level languages are tough. Gaining a mastery of C does require knowing quite a few strange rules and quirks and it's certainly a bit harder than learning Python. The C FAQ does a good job of illustrating some of the more confusing parts. Sure, I wish I could write Go instead, but that isn't going to happen on the many embedded systems I work on. This is a rather strange and insulting article. I'm not sure why Zed…

> Low level languages are tough I disagree. Low level languages, especially C, are the easiest to master. K&R book is the only book you need to read to know everything about C. All you need after you understand the fundamentals is a bit of discipline. C++ on the other hand is extremely difficult to master. Just have a look at the rules for Rvalue references and you will see what I mean. It may be easier for a complet…

I wouldn't say that C is easy to master, but it's not very difficult either.

The problem with C is that even a C master can't necessarily write correct code, because C is a very programmer-unfriendly language, making developers remember to do various actions manually and perform error-prone calculations.

C++ is definitely harder to master (after many years, I can't say I master every corner of the language), but it's much easier to write correct code in C++ and it will be just as fast, run on as many platforms, etc, etc.

C lost this battle a long time ago, it's surviving because of nostalgia, still having good street cred and inertia. The number of domains where one must use C is shrinking and now that we also have Go and Rust this will accelerate. All for the better, really.

Re: Deconstructing K&R C Is Dead (2015)

#95

Earlier quoted context omitted.

The `tmp != head` comparion is UB because `head` is a dangling pointer after the first loop iteration, right?

Yep! To do this properly requires something more like: void free_circularly_linked_list(struct node *head) { struct node *tmp = head->next; while (1) { if (tmp == head) { /* Has to be a separate case since even assigning * a dangling pointer is UB I believe? */ free(tmp); break; } else { struct node *next = tmp->next; free(tmp); tmp = next; } } }

[deleted]

Re: Deconstructing K&R C Is Dead (2015)

#96
post #24

I can't really speak for Zed's expertise and/or value to the programming community. From what I gather, a few of his projects are widely used (Mongrel comes to mind), and he seems to know his stuff pretty well. I also identify strongly with his Programming Motherfucker[0] rant. But man, the guy is insecure to the point of requiring therapy or something. He seems obsessed with his image and status, and the slightest c…

Being passionate about things and having opinions can mean that you eventually burn out on something and for the sake of your own mental health have to move on. I don't think Zed's doing anything wrong. He's saying what he thinks needs to be said, he's challenging the complacent, and he's not pulling any punches. If you don't like his attitude there's plenty of other people to listen to. I appreciate that he's out th…

Maybe being "passionate" is not a healthy state of mind. The community blabbers so much about passion which is nothing more than an almost uncontrolable emotional state.

Screw passion, I'd rather have discipline and a healthy interest instead.

Re: Deconstructing K&R C Is Dead (2015)

#97
post #70

Earlier quoted context omitted.

Out of curiosity, do you have an example? Maybe I live in a C reality distortion field. :)

There are so many to choose from. Here is one I just thought up: void free_circularly_linked_list(struct node *head) { struct node *tmp = head; do { struct node *next = tmp->next; free(tmp); tmp = next; } while (tmp != head); } Can you spot the undefined behavior?

[deleted]

Re: Deconstructing K&R C Is Dead (2015)

#98
post #8

This is obviously a bitter rant, and devolves into uncomfortably ageist territory about halfway through. I do agree that we should be moving away from C and C++, though. It's pretty simple, really: C was a pretty good language in 1978. We didn't know a lot of things in 1978 that we do now in 2016. It now makes sense to revisit those decisions in light of nearly 40 years of practice. The so-called "PL Renaissance" has…

I'm ready for the hate, so here we go... C was not a well-designed language in 1978. The fact that C arrays decay to pointers without any bounds is single-handedly responsible for a huge chunk, possibly even the majority, of all RCEs, worms, malware, and exploits. Ever. In the history of computing. It was a bad design. It was a bad design in 1978. It was known to be a bad design in 1978. Other languages knew that che…

It sure wasn't a bad design for Unix Implementation Language (tm)

Re: Deconstructing K&R C Is Dead (2015)

#99
post #24

I can't really speak for Zed's expertise and/or value to the programming community. From what I gather, a few of his projects are widely used (Mongrel comes to mind), and he seems to know his stuff pretty well. I also identify strongly with his Programming Motherfucker[0] rant. But man, the guy is insecure to the point of requiring therapy or something. He seems obsessed with his image and status, and the slightest c…

Wow, [1] is pretty far out there, what with taking on the worldwide conspiracy to deny him recognition as History's Greatest Genius. Has he at least mellowed out since 2007?

Re: Deconstructing K&R C Is Dead (2015)

#100
post #73

Earlier quoted context omitted.

I suspect this has a -lot- to do with performance. When C was designed, and even today, there are systems without pipelining, where it is expensive (in time) to de-reference a memory address and follow that pointer. I do not argue that the design you suggest would be safer, and even have advantages for slicing; but that's really not the kind of program that C was intended to service writing. Also, C is supposed to sc…

>I suspect this has a -lot- to do with performance. It's questionable whether people wanted that performance though, at least when it resulted in less security. About bounds checking in ALGOL 60: https://en.wikipedia.org/wiki/Bounds_checking A consequence of this principle is that every occurrence of every subscript of every subscripted variable was on every occasion checked at run time against both the upper and the…

"The block structure of ALGOL 60 induced a stack allocation discipline. It had limited dynamic arrays, but no general heap allocation. The substantially redesigned ALGOL 68 had both heap and stack allocation. It also had something like the modern pointer type, and required garbage collection for the heap. The new language was complex and difficult to implement, and it was never as successful as its predecessor."

-- http://www.memorymanagement.org/mmref/lang.html

Adding runtime bounds checking of automatic storage arrays (i.e. arrays on the stack) is relatively easy in C, at least until the compiler runs into illegal type punning. The real problem in implementing these compiler safeguards comes with crossing translation units, or with heap blocks. There's a reason languages like Rust and Go rely heavily on static linking and stack allocation; it's more difficult or more costly to implement those safeguards when the compiler can't see all the source code, or pointers pass through an opaque layer. Nothing in C precludes automatic bounds checking of all array access, via fat pointers or lookup tables. Fabrice Bellard's Tiny C compiler implemented precise bounds checking for both automatic and dynamic storage-allocated objects a decade before UBSan and ASan. Even deriving an invalid pointer crashed the app at the precise point where it happened. That widely-used C compilers don't do that is a strong hint there are other, real-world constraints in place.

Also, in language like Java it's not uncommon to see people reinventing dynamic heap allocation using char arrays, susceptible to all the same overflow problems. When you see people doing that, that should be a hint that a language like C might work well.

I don't understand all the C hate. Then again, I have no problem employing various languages according to the task, or creating DSLs. I suppose if I was wedded to a single language or to the idea of a single language, C would look much worse to me.

Post reply on HN