Learn enough C to survive
codeofhonor.substack.com
codeofhonor.substack.com
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/
Chick-pea must be rolling in his grave.
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.
To be fair, I've encountered Latin the most in philosophical texts which I can't say are read all that often
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.
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.
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’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.
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] = r3All 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.
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...
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...
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.
I think you can eck out more performance, but the time investment is much more.
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.
> 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?
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.
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.
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.
> 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.
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 arguments against learning fundamentals exist, but are weaker than the arguments for.
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!
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.
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.
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?
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.
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.
also c is fun!
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.
Verilog is of course C-like (much as VHDL is Ada-like.)
If you care about execution time, responsiveness, efficiency, or reliability, these things matter.
If you're doing systems programming, they are essential.
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.
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.
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?
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.
Marriage material! :D
(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.
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 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
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.
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.
> 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]
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"
Imagine you wrote a new 3D model file-format and all other language users have to load the Ruby interpreter to use it.
Code of Dishonor
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!
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".
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.
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.
That said, please enjoy the upvotes and I wish you all the best, Jebus.
I do wish I could read this one.
If I switch to a static blog I'll let you know!
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?
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.
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. :)
No, it’s actually crystal clear.
I guess some people really dislike like lame jokes, though!
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.
My impression too. Very unlikely that Linux and BSD kernels will be re-written in Rust.
>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-2022Yes, 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.
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.