120 comments

[ 2.7 ms ] story [ 200 ms ] thread
Just a bibliography of some C books
That's cool, but I am avoiding substack articles because the reading experience is subpar, the registration modal which pops when you are reading and start to scroll down interrupts my concentration and then I bail.

That said, please enjoy the upvotes and I wish you all the best, Jebus.

Have you tried reader view? It's the little button that looks like a document on the right side of the URL bar in Firefox.
I'm on Android..
Which has Firefox and supports reader view.
I don't go out my way to spend time on sites which disrespect the reader.

I do wish I could read this one.

(comment deleted)
(comment deleted)
I appreciate the kind vibes, and I'm sorry Substack isn't an ideal medium (ha) for you. I decided to publish there just because so many writers I admire are there, and I want to write like they do.

If I switch to a static blog I'll let you know!

> Then she handed me a copy of The C Programming Language, which she had just stolen (though at $80, it’s not clear who was robbing whom to begin with).

Code of Dishonor

At least buy it second hand, like I did back in the day.
(comment deleted)
No, she wasn't dishonorable. She took the hard route, risking her own security out of love. I condemn theft, not because it's theft, but because it's harmful. In a utilitarian way, I feel like she helped me more than she harmed B&N. In terms of virtue, she displayed bravery and caring.

She just didn't care about B&N or property law. Maybe you do care about those things - I'm not condoning theft here!

Now, if you had said Code of "This Chick Turns Out To Be Completely Insane And This Should Have Been A Red Flag" you'd be closer to the mark, but that's for the next post!

The “$80 is too expensive” comment is dishonorable. You can choose not to buy something - for books especially considering the library is free.

If you think a corporation is evil, you don’t have to shop there.

>If you think a corporation is evil, you don’t have to shop there.

I don't think charging $80 is evil, but it's a high enough price to merit some light teasing. To clarify: I'm just making fun of B&N for charging a lot for a book I wanted. This isn't meant to argue that charging a lot justifies theft.

>If you think a corporation is evil, you don’t have to shop there.

This is a more interesting argument, that has nothing to do with what I said, but is still fun to think about. Surely, if a corporation is evil, a reasonable response would exceed "don't shop there".

>I don't think charging $80 is evil, but it's a high enough price to merit some light teasing. To clarify: I'm just making fun of B&N for charging a lot for a book I wanted.

Is this really the bookstore's fault? Book prices these days seem to be set by publishers, not sellers, and those prices are actually printed right on the books. The book will cost the same no matter where you buy it, unless the bookseller is discounting it for some reason, but B&N usually sells books at full MSRP.

>Is this really the bookstore's fault?

No, not at all. Like, this morning, my hair looked wild, so my wife teased me about it. It merits teasing, not because the hair was my fault, but just because it was funny looking.

Similarly, I'm making fun of B&N for an aesthetic flaw, not a moral one.

This is so strange : the original Kernighan and Ritchie The C Programming Language book from the early 1980s was a couple hours front to back read, and you're done, and you're up and programming. (Or you're not a computer person at heart perhaps?)

The followup edition I think had the C89 draft ANSI standard, and was the beginning of the way way way more wordy era.

That the idea of "learn enough C to survive" is a concern for anyone seems to mean the concise clarity of the original K&R book is long lost?

The state of modern C is so far removed from K&R that memorizing it probably counts as "just enough to survive".

Someone that doesn't have a good grasp of UB and knowledge of the compiler/machine would be slightly terrifying to let loose in a C codebase.

I've actually seen that happen, and it was not good, as you predict!
I read ANSI K&R, is it yhat much bigger/more complex? Took me about 4 days to read iirc (without doing exercises).
i think 228 pages for K&R 1st edition (1978) which had a long appendix, and 288 for 1988 K&R 2nd edition with draft ANSI standard.

Interestingly, the description from K&R for the 1988 version (I had both btw) said they tried to maintain the succinct clarity of the 1st edition. :)

You should learn C because it's a gateway to deeper knowledge. The kernel uses it, about a thousand programs shipped with Linux use it, embedded programming uses it. It helps you understand how lower level network protocols have been designed, how to efficiently use memory, how to design algorithms and why they're harder than you think. There's a crapton of libraries in C, most higher level languages have some extensions to take advantage of them. Sensitive security software will use it, due to various attack vectors that are slightly easier to deal with at a lower level. It's handy and expands your brain. And it's not going away anytime soon.
Agreed, it helps you understand what’s been abstracted away from you in many higher level languages. From a security perspective I think you learn to avoid C wherever possible.
(comment deleted)
Isn’t that the same argument we used to use with Latin? It would be nice if we could all stop time and learn the fundamentals better. However, in the reality we actually live in, most of my coworkers don’t even have time to truly learn SQL, let alone C.
I never happen across works written in Latin. I come across a lot of C code.
Lorem ipsum?
From the wikipedia entry[1]:

Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a 1st-century BC text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical and improper Latin.

I don't think that really counts as "latin", any more than hackertyper[2] counts as C code.

[1] https://en.wikipedia.org/wiki/Lorem_ipsum [2] https://hackertyper.net/

Yeesh, is nothing sacred?

Chick-pea must be rolling in his grave.

On behalf of the poster I'd like to say mea culpa. It was kind of an ad hoc example though, and perhaps they didn't mean that specific example per se but more the large number of Latin phrases one comes across daily without really thinking about it.

I guess we could continue this thread ad infinitum because there are plenty more examples but I'll leave this as de facto proof that Latin remains used: Et cetera.

... AD, et al, ibid, n.b., i.e., e.g., etc.

To be fair, I've encountered Latin the most in philosophical texts which I can't say are read all that often

It isn't necessary to learn Latin in order to be familiar with words that are de facto English words.
I would posit that for Latin words and phrases to have become “de facto” English is ex post facto the historical prevalence of people having learned Latin.
Yes. If you use e. g. numerical libraries, and wonder what really does this algo do often you look at C. If you dig too deep then you look at fortran though...
I can't say I learned much by programming in C, if I even learned anything at all. Mostly I just grumble at the needlessly verbose and complex way of doing some things (e.g. anything with strings) and get annoyed by the syntax and quirks of the language and surrounding toolchain.

It is of course useful for a whole bunch of reasons, including being able to figure out "why does this do X?", but that's not really "deeper knowledge", IMO.

Compared to writing code in assembly language it is a dream, though!

I think C lets you think about low-level details of how systems work, strings being arrays of characters with an explicit terminating NUL character, for example. Although again assembly language gives you _real_ lower-level understanding and insights if you use it.

It's useful to know how things like strings and arrays work and that they're not just "magic", but I don't think you really need to learn C to do that. I understood that kind of stuff long before I did any serious C programming, and knowing C didn't really add much to that. The thing is that I don't want to think about it every time.

I "just" want to do X, but instead I need to write a whole bunch of code to handle it all manually. It's useful that this is possible, but a lot of times you don't need it, and some other languages still keep the "common case" easy while still enabling the high-performance stuff C can do.

I wish we had C+: C + a few niceties (and not C ++ everything). There's a whole bunch of newer languages aiming at the space C is sitting in, but with a few additions C could be much more ergonomic without having to invent an entire new language.

> I wish we had C+: C + a few niceties (and not C ++ everything). There's a whole bunch of newer languages aiming at the space C is sitting in, but with a few additions C could be much more ergonomic without having to invent an entire new language.

I’ve made a pre-processor for C to add some things I miss, although it is currently limited to what can be done without type information and has to keep compatibility with existing C syntax: https://sentido-labs.com/en/library/cedro/202106171400/

There is another language called C3 that “is a C-like language striving to be an evolution of C, rather than a completely new language”: https://github.com/c3lang/c3c

If you have the time, I’d like to hear which things you miss in C. There might be something I did not imagine that could be added to Cedro.

> Compared to writing code in assembly language it is a dream, though

C is a something of a high-level assembly language. Of course we could write literal assembly language in C, pretty much.

   r1 = 0
   r2 = 1
   r3 = r1 + r2
   mem[1000] = r3
Except that C targets the C abstract machine, which can't do a lot of stuff that is perfectly acceptable in assembly. Such as reading uninitialized memory, padding, overflowing signed integers, forging a pointer (e.g. for memory mapped I/O) out of thin air, dereferencing null...
By the way, null-terminated strings are not the only way to express strings, it’s a legacy of C that many low-level programmers dislike but need to stick to it because of legacy reasons (every major OS is written in C).

All the low-level languages aiming to replace C basically abandoned this approach, and opted for slices instead (ptr + size pair, used in Rust, Zig, etc.) This has the benefit of easier and faster string manipulation (strlen can be O(1) instead of O(n)), as well as better memory safety (can do bounds checking with the size information). The primary reason we are still using and teaching null terminators is because we still have to live with POSIX/Win32 and many low-level libraries written on this platform.

Indeed, I remember Turbo Pascal, running under CP/M, used the scheme where strings where prefixed with their length rather than being NUL terminated.
I thought zig has null terminated string literals. What's the difference?

String literals are constant single-item Pointers to null-terminated byte arrays. The type of string literals encodes both the length, and the fact that they are null-terminated, and thus they can be coerced to both Slices and Null-Terminated Pointers

https://ziglang.org/documentation/master/#String-Literals-an...

Hmm... after some research it seems that I've misunderstood Zig's situation a bit. Zig has introduced null-terminated string types a couple of years ago, but still encourages you to do most string operations with slices instead. Let me explain:

Zig's string literals (which you create with parenthesis like "Hello world!") are null-terminated byte arrays, expressed as the type *const [N:0]u8 (where the :0 tells you that it's null-terminated), whereas the more typical array might be written as *const [N]u8. The reason for this feature is not because the language wants you to use null-terminated strings, but because these static strings need to be stored in the global data section of the ELF executable, and these require you to use null-termination. But if you want to do any mutable operation with this string, you need to convert this into a proper slice (ptr + size). And it seems like Zig developers don't really use null-terminated types that much at the API level, but use it for things like C interop or cases where you really need it for special optimizations.

Noting that from the PR that introduced this feature, Andrew Kelley writes [0]:

> I think you will find that the Zig community in general (and especially myself) agrees with you on this [null-terminated strings being fragile], and APIs in general should prefer slices to null terminated pointers. Even if you are using Zig to create a C library, and even in actual C libraries, I would recommend pointer and length arguments rather than null terminated pointers, like this: https://github.com/andrewrk/libsoundio/blob/1.1.0/soundio/so...

> That being said, I want to repeat what I said earlier about null terminated pointers: A null terminated array is not inherently an evil C concept that is intruding in the Zig language. It's a general data storage technique that is valid for some memory constrained use cases. I also stumbled on a Real Actual Use Case inside LLVM. The bottom line for me is that null terminated pointers exist in the real world, and especially in systems programming. You can see this in interfaces with the operating system in the standard library...

So he acknowledges null-terminated strings can certainly be useful in certain situations outside of legacy reasons, which is good to know. And Zig creating a special type for this shows that a good systems language needs to be designed to accommodate the needs of the outside world.

[0] https://github.com/ziglang/zig/issues/265#issuecomment-46337...

Thanks for this nice writeup!

Small correction regarding the ELF object file format: any kind of data whatsoever can be stored in the data section, including strings in the form of ptr + length without null termination. Zig string literals are null terminated in addition to having the length not because of an object file limitation but because it is useful to pass string literals to APIs that require null-termination, such as most C libraries. In practice, this simplifies the experience of using the language.

Imo the string thing is a bad example, as they don't really have to work that way. Storing length is another solution, but because C is C, the NUL method is quite prominent, if annoying
even assembly is essentially bytecode on the modern processors.

I think you can eck out more performance, but the time investment is much more.

Time is finite. Learning C is not necessarily aligned with everyone's goals or path. For example, if I care more about building products than low level software it's probably not worth learning C unless I happen to be interested in it.
To me that seem akin to saying "if you just care about running it's probably not worth learning to walk"

It is always "worth it" to understand the machine you are manipulating, and no matter what you think about the C virtuel machine, the very real machine in front of me has been shaped by its relationship to C.

The difference is that you could go your whole career without needing to touch C, whereas to run you must walk.

> It is always "worth it" to understand the machine you are manipulating

Why is it always worth it? If I want to be a product/creative developer how does learning C specifically help me?

C confers an understanding of pointers that will cause reference types in other languages to make a lot more sense. It'll also give you a good feel for what kinds of operations are costly and what kinds are not.

It's like knowing how your car works will make you a better driver. You'll be able to get more out of the car, it will last longer, and when it breaks you'll know if you can't move another inch or you'll know how to nurse it home.

> C confers an understanding of pointers that will cause reference types in other languages to make a lot more sense

I'm not sure what you mean by this. I know what pointers are and I have not written C before. What understanding will C specifically give me which will help me understand reference types better?

> It'll also give you a good feel for what kinds of operations are costly and what kinds are not

Does this matter though? For most applications you don't need to understand what kind of operations are costly.

I am unusually curious so I'll probably learn about Assembly and low level operations out of curiosity at some point, but it's easy to imagine that I may not work on something where this would be useful knowledge or I would use this knowledge so rarely that the opportunity cost is not worth it.

For the vast majority of developers the opportunity cost for learning C seems quite high.

> I know what pointers are and I have not written C before

Actually working with them confers a lot more understanding of them.

> For most applications you don't need to understand what kind of operations are costly.

I've often been given the task to fix severe performance problems in other peoples' code who simply did not know what kinds of operations were costly. Having performant code is a significant competitive advantage.

> For the vast majority of developers the opportunity cost for learning C seems quite high.

Not if you understand pointers. That's what usually trips up people new to C.

> it's easy to imagine that I may not work on something where this would be useful knowledge

This may be hard to explain, but you don't know what you don't know. You won't be able to see an opportunity to exploit your knowledge gained from using C. To go back to the car analogy, most people drive a car with zero knowledge of how it works. This winds up being expensive for them, when it's time to deal with problems with the car.

For example, the alternator shorted out in my car. I took it to the dealer for a repair, and they quoted me a fantastic sum including 2 hours of labor. I happen to know how the alternator works, and I've replaced alternators multiple times. I gave the service manager the step-by-step procedure to replace the alternator, and said it could be done in 15 minutes tops. The labor price quote dropped by more than half. It also turned out that they could get me a refurbished one for far less money, and since I understand what a refurbished alternator was, I was comfortable with installing a refurbished one.

Anyone not knowing how cars work would have had no ability to bargain or understand the tradeoffs.

Many languages other than C have pointers though. It sounds like you are recommending understanding pointers moreso than learning C.

> I've often been given the task to fix severe performance problems in other peoples' code who simply did not know what kinds of operations were costly

What kind of application was this? I completely believe having this knowledge is valuable, but not for all developers.

> This may be hard to explain, but you don't know what you don't know. You won't be able to see an opportunity to exploit your knowledge gained from using C

This comes back to opportunity cost. You are stating this as though C is the only avenue to gain knowledge which can be exploited at a later date. For many developers there is probably other knowledge which is going to be far more useful and exploitable.

Your story about the alternator feels like a good example of this. If I was in your shoes I would have paid the original sum and been happy. You've saved money, but you've also had to learn how an alternator works and replace them multiple times. I'm happy to pay a premium and use that time for other things.

C is a small and straightforward language. It's easy to learn. It's the lingua franca of the programming languages (in that the foreign language interface of other languages is usually C). You're possibly expending more effort justifying not learning C than it would take to learn it :-) And once you learn it, as a professional programmer you'll garner a career's worth of benefit from it.

Take the plunge. Learn how to swim, how to touch-type, how compound interest works, how to read a balance sheet, how to tie various knots, how to drive a stick shift, how to integrate and differentiate, how to unclog a drain, how to jump start a car, how to change a tire, how to write a program in C.

As an old guy, I know these simple skills pay off in various and unexpected ways.

The alternator is a specific item example, a stand-in for a tax on everything in life 100 times a day every day.

The arguments against learning fundamentals exist, but are weaker than the arguments for.

There are languages that have pointers and don't require understanding a bunch of random arcane rules just to declare a variable.
C's problems stem from its simplicity, not its complexity.
They stem from both.
> Why is it always worth it? If I want to be a product/creative developer how does learning C specifically help me?

I am going answer you with some questions!

What is a product for you?

Are a dishwater, a car, a keyboard, a smart LED lightbulb some kind of product a human can build? A product with some sort of microcontroller?

How many products like that there are in your room, house and office right now?

What about in the whole world for the past 20 years?

In all of those products there is probably C running!

I thought it was obvious from context that I was talking about software products.

This is what I mean by a product developer: https://blog.pragmaticengineer.com/the-product-minded-engine...

I'm sure that type of developer exists for the kinds of products you are talking about, deep tech products, etc but that seems a lot less common.

But those developers write software just like you! These products are also "software" to some degree!

The link you've posted also applies to those who build smart lightbulbs.

> seems a lot less common

I guess the problem is that the world is bigger than you may think. I don't know what you build, but let's pretend it's some kind of web service.

Consider how many brands of microcontroller-based products there are in the world, with their many variants. For the sake of the discussion consider just the "commercial" products you can purchase on Amazon. My guess is that they surpass the quantity of web projects out there.

Add to the mix the custom/industrial devices, special tools and computers, etc. that many small companies are building right now (like the one I work for).

Remember that someone is writing code for these products. Given the quantity of product, they can't be "a lot less common".

To answer your question, and if you do web services, let's say you want to know how Redis works internally. You need C.

To me this demonstrates why it's not always worth learning C. Like you said, the world is bigger than we think. There are areas of software where knowing C is not that helpful.

Even in the web world, most devs are not going to be poking around in Redis internals. If you go higher up the stack to things like accessibility or CSS animations then knowing C is literally useless.

Why do you feel like C is so fundamental that every developer must know it regardless of what they work on?

> Why do you feel like C is so fundamental that every developer must know it regardless of what they work on?

I never said so. I was answering specifically to "If I want to be a product/creative developer how does learning C specifically help me?"

Since you didn't mention what you do, I was talking about "product" and the definition you have, and if you want to build "product" there is a whole "product" industry, that is bigger than you think, that requires C.

If you do web development you can completely skip it if you want, but C is a nice tool to have around to understand why there is a bottleneck in Redis, Sqlite, a driver or a stack. Maybe find a workaround or a fix, but waiting for someone else to fix it is also valid if you don't want to fiddle with C.

It happens all the time: high level developer points finger and says "there is something wrong with the filesystem, my app crashes". They cross their arms and wait for me to go in a crazy debug session so I can explain them later why their app is slow and/or crashes.

It sounds like we have no disagreement then?

I'm well aware there are a lot of places C is used. My point is mostly that "waiting for someone else to fix it ... if you don't want to fiddle with C" is probably a better strategy than becoming competent enough with C to fix your own problems.

Becoming competent enough with C to diagnose and fix problems in production C codebases seems like it would be quite time consuming.

Also, I work with SREs that debug problems with MySQL and Redis without knowing C or looking at C code. Unless you are actively contributing to those codebases it seems unlikely you need to know C.

c helps one understand the limits of what is possible. those limits change over time. without good intuition of those limits, you can’t see the whole solution space that you are creating within, and can’t reason about tradeoffs of different solutions.

also c is fun!

I mean, if that's going to be your justification for learning C, then shouldn't you be learning how to create 16 bit adders from flip-flops, learning about the importance of mux and demux chips, and then building an ALU and FPU in verilog and testing them in a simulator?

I would argue that assembly language and hence C has been shaped that way it has because of the underlying structures of the processor and the way binary numbers are manipulated and stored. C and for that matter assembly, becomes quite trivial if you know enough to make your own simple CPU with decoder, instruction set, memory, ALU, FPU, etc.

I tend to think (agree with you?) that understanding computer architecture will make you a better system designer and developer. That's probably why many CS programs (and systems concentrations in particular) require a computer architecture course.

Verilog is of course C-like (much as VHDL is Ada-like.)

This comment is far from reality. It's difficult to measure what a "good" programmer is, but regardless of decision I am confident that it will have no correlation with whether you learned Verilog or what a D Flip Flop is.
Missing the forest for the trees. Computer architecture courses often expose you to things like: caches, memory and storage hierarchies, I/O, software/hardware interface, parallelism, Amdahl's law, pipelining, vector processing, prefetching, speculation, synchronization, clocking, interrupts, vector processing, data encoding, stream processing, virtual memory, general virtualization, isolation etc., etc..

If you care about execution time, responsiveness, efficiency, or reliability, these things matter.

If you're doing systems programming, they are essential.

I actually agree that moving in that direction is useful. I happen to have started from a quite high level (C# and VB.net), but I've been steadily moving down the stack towards embedded devices. I've been surprised many times by how many problems we've created for ourselves, and how much easier they become once you simplify.
This doesn't make sense in my point of view, since C is itself an abstraction. Why not do everything in assembler? Most of the early C compilers featured inline assembly.

Do you learn how to fly when you book a flight? Do you learn how to build cars when you get your driving license? Do you learn how water is cleaned when you drink? There is infinite regress.

In the end it is about trust and abstractions. Most algorithms have nothing to do with C. They are implemented in C.

C is a great language, but as someone said here, there is only so much time.

Learning to program in C taught me to appreciate how amazingly powerful modern computers are, even off-the-shelf commodity hardware. It helped me realise that if I code something and it isn't blindingly fast, I'm probably doing something wrong.

And how many people who can't even be bothered to learn C will dive even deeper into assembly?

And yes, I would think anyone who books flights/drives/drinks water for a living would be well served by learning something of the tools of their trade.

We are not booking flights or taking driving lessons. We are (hopefully) engineers and scientists. I find it perfectly acceptable that you chose to accept the abstraction of the machine. You may benefit from knowing electrical engineering, but I believe the benefit is slight. Knowing the history of the field is non negotiable however.

You don't need to know how to heel-toe to drive to the market, but pretending that it's not a useful skill to master driving is ridiculous.

Are you driving to the market, or are you a serious professional?

I was able to learn that deeper knowledge without learning C, via Sinclair Basic, Turbo Basic, Turbo Pascal, Z80 and 80x86 Assembly, before eventually learning C.

And it wasn't even proper C, it was RatC at the time.

There are plenty of alternatives to expand our brain in systems programming, and even better they show we don't need to compromise on security to do it.

However, yes one needs to learn C, because it has snuck everywhere and as the COBOL of systems programming languages (ruffly 10 years younger), it isn't going anywhere.

If you want to be a Haskeller, learn some C too. They are fully complementary. The Linux tooling, gamedev libraries, etc you have available if you leverage C is great. And Haskell's FFI and C tooling making it simple.
> Then she handed me a copy of The C Programming Language, which she had just stolen (though at $80, it’s not clear who was robbing whom to begin with).

No, it’s actually crystal clear.

I think that’s a joke
(comment deleted)
A go-to strategy of responding to lame jokes is to pretend you don't understand them and make the other person to painfully explain until it becomes crystal clear for every party how bad they are
My goto strategy is to laugh at how silly the joke is, rather than try to make people painfully explain something to show everyone how bad the joke is.

I guess some people really dislike like lame jokes, though!

It also works with inappropriate innuendo.
Isn’t a more future-proof approach to learn Rust instead? Linux kernel is incorporating Rust, and programmers often adopt open source packages written in their favorite language. Rust being the most favorite language for 5 years in a row must say something.
Learning Rust is certainly useful!

But C is not going to disappear, and the huge reams of important code written in it, like the Linux kernel proper, are not going away, too.

But C is so much simpler than Rust, it comes almost free. It does give you an appreciation what really unsafe code is, and why is it so unsafe. It also gives you a better understanding of how the machine works on the lower level.

>> But C is not going to disappear

My impression too. Very unlikely that Linux and BSD kernels will be re-written in Rust.

It may happen. It would kill both projects, because Rust is arguably future-proof in its syntax.

  >Rust is arguably future-proof in its syntax.
I'm not so sure about that. Given how many people dip a tentative toe in the Rusty waters and give up, baffled by the arcane syntax, I really wouldn't be surprised if Rust-2032 bore little resemblance to Rust-2022
Is C actually simpler than Rust? It's certainly less powerful, but it has so many weird edge cases (e.g. the integer promotion rules) that I'm not convinced it's actually easier to learn fully.
Honestly, knowing C made it much easier to understand why design decisions from Rust matter. I see Rust as kind of a (welcome) reaction to the memory model that C++ inherited from C.
To you and @nine_k:

Yes, I agree with the fact that learning C makes us appreciate Rust (and other safer languages) better. It's just that between C and Rust, I would pick Rust. I'm not a systems programmer, but I have worked with C before and as soon as I saw some of Rust's example codes, I liked how it taught me something and liked the design choices. Rust does seem like a nice language.

I love Rust, but being the most favorite language and being an essential language to know in some sense (read, write, understand) are two different things.

C is primitive and painful to program in for the most part. However, it's at the core of plenty of important things, so having enough knowledge to get around it is crucial.

C is essentially a portable assembler and it's great for a number of tasks. Rust is a general-purpose programming language and it has a vastly different domain of application. Surely, they overlap, in some domains Rust is overtaking C (where C was used more out of necessity/lack of alternatives rather than consciousness). The point is, though, is that there is a domain (not necessarily very big, but very important) where C will very likely stay for a very very long time. At the same time, Rust is great, but not much critical software is written in Rust (yet). It's likely that there will be such software in the future, but I think the consensus is that nobody knows for sure.

Popularity is a poor measure of a programming language's worth. Remember, there was a time Perl was popular and, an much as I love Perl, it has some issues.
I've started learning C after I have learned Rust. Maybe not everybody needs it but once you are going to do FFI you are exposed to some C.
"On my 18th birthday, my girlfriend asked me to drive to Barnes & Nobles. She strolled in, then strolled out at a much faster pace. Then she handed me a copy of The C Programming Language, which she had just stolen..."

Marriage material! :D

(1) She didn’t plan his gift ahead of time.

(2) She made him an accessory to a crime.

(3) She stole his gift instead of investing actual effort to save up and purchase it.

I know the world will always have its share of thieves and liars, but I’m still always a little taken aback when people are shameless enough to celebrate it.

The bare minimum for “marriage material” would have been putting thought into his gift before his birthday, buying it, wrapping it, and surprising him with it.

you missed the point and/or joke, which is implicitly that crazy girls are great in bed
(comment deleted)
I can settle this debate:

1. She turned out not be marriage material

2. Y'all are way too sensitive about a teenage girl who shoplifted one time.

It’s not about the errant teenagers — although I think we can and should expect more of even teenagers.

It’s about how you framed and excused your behavior.

>It’s about how you framed and excused your behavior.

No need for excuses whatsoever - if someone on here has a stolen book they want to gift me, I'll accept it with no shame or guilt. The joke wasn't meant to be an excuse, but for what it's worth, my emotional frame towards what she did is gratitude.

I'd love to discuss this with you, since we have interestingly divergent viewpoints on how I should have reacted. Feel free to hit me up: the.jesus.aviles [at] gmail.com

> if someone on here has a stolen book they want to gift me, I'll accept it with no shame or guilt.

Knowingly accepting stolen property is both unethical and illegal.

This isn’t an unexplored ethical frontier; I appreciate the offer for further discussion, but I don’t think there’s anything novel either of us can contribute on the subject.

> but for what it's worth, my emotional frame towards what she did is gratitude.

Sounds to me like the basic conflict here is the OP holds to expressive individualism of the sort historian Carl Trueman describes in his book, The Rise and Triumph of the Modern Self [0]; while the commenter appears to believe that moral/ethical reality exists external to human persons, thus stealing and being an accessory to theft are wrong, regardless of one's emotional frame.

Thats interesting, are you saying there are serious people who claim that the wrongness of theft depends on the emotional frame (and havent been paid by russia over the last decades with the intention to subvert western society?)
She advocated for something incompatible with the complete prohibition of the C programming language, which is a far greater crime than the theft of any physical object.
I'm not entirely sure if I would want my future wife to be a shoplifter.
Learn enough C so that you can push your module written in Java/Ruby/Python/Node into C, and all the other high level language users can pick it, compile it and use it natively in their language.

Imagine you wrote a new 3D model file-format and all other language users have to load the Ruby interpreter to use it.

> Beej’s Guide to C Programming > It’s straightforward and to the point.

I'm not saying its a bad book/guide, but with sections like these:

>Before we go on, why would I even begin to bother pointing out that a pound sign is called an octothorpe? The answer is simple: I think the word octothorpe is so excellently funny, I have to gratuitously spread its name around whenever I get the opportunity. Octothorpe. Octothorpe, octothorpe, octothorpe.

It claims to be aimed at programmers who are already proficient in high-level languages, but spends a whole paragraph explaining what code comments are.

I'm not sure it qualifies as "to the point"

Ha! You've got me, "to the point" is going too far. But I should say that it's a relatively quick, light read. Moments like the octothorpe thing actually make the read easier, because the humanity of it makes my brain wake up a little.
> Programming from the Ground Up

> https://download-mirror.savannah.gnu.org/releases/pgubook/Pr...

There is an updated version of the book from the author: "Programming Under the Hood" or "Learn to Program with Assembly". See[0]

[0] https://github.com/johnnyb/programming_under_the_hood

What a great book! It was my introduction to 32-bit assembly on Linux. Learning AT&T syntax has both its advantages as well as drawbacks. I've noticed a lot of GNU code uses it, whereas reverse engineering literature loves Intel syntax, which is an interesting cultural difference.
(comment deleted)