Live data from Hacker News

Deconstructing K&R C Is Dead (2015)

c.learncodethehardway.org

151–160 of 190 posts

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

#151
post #2

I am one of the many stalwarts whose bookshelf contains a prominent copy of K&R C. But over the last 10 years or so I find myself referring to it less and less often. It's a huge problem that it stopped at the second edition. The 2nd ed was great in 1999. It is not great in 2016, it is only good. > "You're right, but you're wrong that their code is bad." I cannot fathom how a group of people who are supposedly so int…

The thing is, I think you can simultaneously have all of these opinions: (a) K&R were/are top-notch computer scientists; (b) K&R was a fantastically written book; (c) C was a great language in 1978; (d) we should be moving away from C in 2016. The fact that we didn't know as much about programming languages in 1978 as we do now in no way diminishes the significance of the work. I think that C should rapidly be moving…

Agreed on all accounts.

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

#152

Earlier quoted context omitted.

Your interpretation of "codify common existing practice" would imply that no new compiler optimizations could be implemented since 1990 (when the first version of the standard was published), as any optimization could potentially change the observable execution behavior of an erroneous program that contains UB. > More from the standard (defining UB): Your quote is not from the normative text of the standard, but from…

> Your interpretation of "codify common existing practice" would imply that no new compiler optimizations could be implemented since 1990 Utter nonsense. I use that word carefully, but in this case it is absolutely appropriate. Compiler optimisations per an old but very useful definition aren't allowed to change the visible behaviour of programs (in terms of output, obviously they are allowed to change execution time…

> Unsurprisingly, you left out the second part of the (later) definition:

It is not part of the normative definition, which says "for which this International Standard imposes no requirements". In ISO standards, notes are without exception non-normative.

Although I think they really should add your proposed text as an additional example, as their current set of examples is evidently confusingly incomplete :-)

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

#153

Earlier quoted context omitted.

> especially with modern UB-aggressive optimizing compilers. You put your finger on the problem: "modern UB-aggressive optimising compilers". C, the language, is actually quite simple (if not easy). The crazy stuff that compiler writers have been doing recently while aggressively mis-reading the C standard is the problem and does make things very complicated. Why "misreading"? From 1.1: "The X3J11 charter clearly man…

Your interpretation of "codify common existing practice" would imply that no new compiler optimizations could be implemented since 1990 (when the first version of the standard was published), as any optimization could potentially change the observable execution behavior of an erroneous program that contains UB. > More from the standard (defining UB): Your quote is not from the normative text of the standard, but from…

>Note however that it explicitly says that programs that contain undefined behaviors are erroneous

No it doesn't say that. It says that they are either "nonportable" or "erroneous". I'll take "nonportable" for 400, please.

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

#154
post #146
post #142

Earlier quoted context omitted.

The term "ad hominem" is typically used to describe the fallacy of attacking the person making an argument, rather than the argument itself. Sure, I'm discussing his character, but I'm not trying to win any argument here - he may be correct in what he's saying. > The guy invested his time and effort trying to improve the world by writing a technical book, which he then proceeded to give it away for free And I think t…

> The term "ad hominem" is typically used to describe the fallacy of attacking the person making an argument, This is a discussion on a book on the C programming language written by someone, and here you are going full throttle on your personal vendetta against the author while saying absolutely nothing regarding the book or the programming language. > Sure, I'm discussing his character Precisely. Go vent your frustr…

Please stop dictating what this discussion is about, and what people can and cannot discuss here. This is perfectly relevant.

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

#155

Earlier quoted context omitted.

Your interpretation of "codify common existing practice" would imply that no new compiler optimizations could be implemented since 1990 (when the first version of the standard was published), as any optimization could potentially change the observable execution behavior of an erroneous program that contains UB. > More from the standard (defining UB): Your quote is not from the normative text of the standard, but from…

>Note however that it explicitly says that programs that contain undefined behaviors are erroneous No it doesn't say that. It says that they are either "nonportable" or "erroneous". I'll take "nonportable" for 400, please.

As the "rationale" document points out, implementations are free to do something well-defined in the cases that the standard considers UB. For example, an implementation may document that it detects out-of-bounds array reads and these always return the value "0", and a hypothetical "C" program could rely on that. But implementations explicitly aren't required to do that, hence code that relies on a particular interpretation of UB in a particular implementation is nonportable, since it is a program written in an extended dialect of C, not ISO standard C.

Options like GCC's -fwrapv/-ftrapv and -fno-strict-aliasing are examples of language extensions that are essentially implementation defined UB.

Edit: Of course you could argue that things where hardware difference are a likely motivation such as signed integer overflow ought not to be UB in the first place, but instead left as implementation defined in the standard, but in that case your issue is with the C standard committee, not with implementers.

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

#156

Earlier quoted context omitted.

What in particular makes Rust (or Go or Swift) unsuitable?

GC languages are almost certainly not even in consideration for most embedded applications. There aren't good strategies for general garbage collection that don't insert random pauses for starters, and you also have a non-negligible impact on RAM usage on systems where RAM might be a premium. A lot of the things rust brings to the table aren't always relevant on embedded platforms. Dynamic memory allocation on embedd…

  > GC languages
Rust is not a GC'd language, it essentially uses RAII to deterministically determine at compilation time when memory will be freed.

  > Dynamic memory allocation on embedded is the exception
Rust fully supports running entirely without dynamic allocation. There is a subset of the standard library defined explicitly for this purpose.

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

#157

Earlier quoted context omitted.

What in particular makes Rust (or Go or Swift) unsuitable?

Doesn't the design of Go, the language, basically require that the implementation involve a runtime with a GC system? So that would make it a non-viable choice for programming in applications where memory footprint and real-time performance must be tightly controlled. Rust is a better choice, and it's designed with this in mind. It's still young, though, and I think there might be some as-yet-unsolved issues (these a…

  > like binary size, ease of dealing with raw pointers, etc
The majority in the size of typical Rust binaries is the huge amount of space (400 kb or so) that it takes to statically link jemalloc. But if you're building for a device that doesn't support dynamic allocation then you're not going to be including jemalloc, so binary size shouldn't be a problem.

As for raw pointers, they're exactly as capable as raw pointers in C, though they're deliberately more verbose as well, because even in embedded contexts one should be favoring references over raw pointers, since references are still fully checked for safety even in embedded mode and yet are represented by raw pointers at runtime and hence have zero runtime overhead.

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

#158
post #81

Earlier quoted context omitted.

Calling C from Rust is very convenient. All you have to do is declare the structs and function signatures and then it's like calling any other unsafe function.

IMHO it is OK if you are only going to call a few simple one, but for calling a few hundred complex ones (callbacks with variable argument list, etc..), it becomes a bit cumbersome. BTW I am not implying that is Rust's fault, actually I can't think a syntax that would make it less verbose, and I am a huge Rust fan.

For very extensive C APIs like this (Lua, GTK, etc.) we typically see people create thin, Rust-friendly wrappers to reduce the amount of manual API calls that need to be written out.

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

#159
post #23

Oh Zed. Really? There is nothing wrong with carefully crafted C code for applications were it is the best suited tool. Sure, there are sharp edges. True you can write crappy, security nightmare code. You do make some good points. I agree Go is fantastic. Rust is coming along as well. However, C still runs the world. That's not changing anytime soon. Not with the explosion of IoT and GPU type devices. And, hello Linux…

  > Try using Go or Rust (love both, x2 for Go) to allocate 
  > say a hundred GB of memory for some huge/fast in-memory 
  > data processing.
Why would this be a problem in Rust? It literally doesn't impose any overhead on memory consumption, at least not any that C doesn't (e.g. padding). Dropbox has clusters of machines that manage exabytes of data whose core is written in Rust.

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

#160
post #132
post #76

Earlier quoted context omitted.

I'm sorry this wasn't clear; I was subconsciously waxing poetic. I meant to say that C's presence is constantly fading but its influence is widespread.

There's a difference between fading away and the universe expanding. Once upon a time most Unix software was written in C, shell, and awk. Then Perl came along. Did that diminish C? No. Then Java. Did Java diminish C? No. Then Python. Did Python diminish C? No. (You can throw C++ somewhere in there; not sure where. Though IME C++ use really seemed to explode with Windows developers migrating to Linux.) In each case t…

  > Compilers are free to add bounds checking at every 
  > point in the program; in most cases it would be just as 
  > cheap as in C++ or even Rust.
It would not be as cheap as in Rust because Rust uses an explicit standard library feature (iterators) to obviate the need for bounds checks in the vast majority of loops to begin with. But in C indexing is pervasive within loops, so you'd need to come up with much cleverer compilers that could manage to prove that bounds checks were unnecessary (compilers can already do this in some cases, for C/C++/Rust, but it's not perfect).

Likewise, one could make integer overflow in C well-defined, but this would also make C slower than Rust because the use of iterators means that Rust doesn't need to check for overflow on each loop iteration. Via language (or rather, library) features, Rust reclaims the performance that it otherwise would have lost to C by dint of being free of undefined behavior. I think you'd have a hard time doing this in C without rewriting every `for` loop in existence.

Post reply on HN