Live data from Hacker News

To become a good C programmer (2011)

fabiensanglard.net

81–90 of 135 posts

Re: To become a good C programmer (2011)

#81
post #76

Earlier quoted context omitted.

If you are troubleshooting software problems in any language (except, usually, Java), sooner or later you dig down and hit C or C++. In those cases knowing C means you can solve the problem. There are a lot of libraries written in C, like, thousands in Debian alone. You can use them from any language, but sometimes you need to write a little bit of glue C to get that to work. Sometimes it's less painful to just write…

> Getting things to work all the time is easier in Rust than in C or C++. Getting things to work some of the time is easier in C. I think this is a good generalization of the learning curves of the languages, but not necessarily productivity for an experienced developer. Rust has modern amenities like pattern matching, generics and a package manager.

You may be right; I'm still a novice at Rust. I've heard people with substantially more experience in Rust telling me they still find it slow going compared to C, but they may not be experts, and they may not be representative. And surely in domains like compilers, which benefit more from pattern matching and automated storage reclamation, Rust would have a significant edge.

Re: To become a good C programmer (2011)

#82

Earlier quoted context omitted.

> It is also great at making you aware of the machine. In C, very little is happening behind the scene. This is not true. It hasn't been true for decades. C is an abstract high level language on modern processors. https://queue.acm.org/detail.cfm?id=3212479

True, but if it is still possible to be a C programmer who can more or less imagine what assembly will be generated (at lower levels of optimization at least) by their C code, then isn't the real issue that x86 assembly abstracts away a lot of hardware info about caches, pipelines, microcodes etc? In that case how can a low level exist on x86?

I'm not sure that's true. There was a highly upvoted post recently on both HN and /r/programming that claimed to have a better sorting algo than libc's sort. After hundreds of comments across both forums, looking into compiler explorer showed that the key difference was inlining.

As a C++ person, basically all micro-optimizations start at "look at the damn assembly" since people really suck at predicting what code will actually be generated.

Re: To become a good C programmer (2011)

#83

One of the things I tend to think about these days is return on investment. I spent several years at the beginning of my career being a bad and then mediocre C programmer, and once I found a few other languages, I got the sense that being a mediocre-to-good programmer in these languages would be much easier, and that seems to have been borne out. Late into a career investing in other areas, what's the advantage of be…

My take is this:

C is necessary in some paradigms/domains. But that list has been shrinking as other languages are born and mature.

Learning C, like learning most things, will still certainly lend itself to lots of things you do, even if you're not using C.

Why learn C? Because you want to do stuff on that list or because you feel like it. Why not learn something else instead? It may very well be that there's more worthwhile things to learn depending on your goals.

Re: To become a good C programmer (2011)

#84
post #26

> No website is as good as a good book Good (and often forgotten) advice for more than just C...

I don't agree with this sentiment. People learn different ways. I personally learn through trial and error, and explanations of things that I haven't been able to "touch" yet don't help me at all.

> I don't agree with this sentiment. People learn different ways. I personally learn through trial and error, and explanations of things that I haven't been able to "touch" yet don't help me at all.

Learning through trial and error can be okay for custom problems that don't have well defined solutions. For simple problems, it's highly inefficient. Extreme example: if I want to print something to the console in C, I can use trial and error for a half-hour to try to understand the nuances of how to use printf(), or I can read for a few minutes a few pages in a book or an (good) online tutorial. Not only will I learn faster, I will also learn best practices.

My experience has been that people who are really against learning through books/tutorials tend to have short attention spans. Which is okay—books don't work for you. But for people who do have the ability to sit and read, it can be much more efficient than struggling through trial-and-error.

Somebody has already solved your problems, and they can tell you in a few pages how you can solve them too.

Re: To become a good C programmer (2011)

#85

I feel like I wrote that a decade ago. Wait. Damn. It WAS a decade ago. Amazingly the list is still relevant. I will try to check out the new suggestions on this thread.

Has your book recommendations changed in this decade? Would you recommend different books today?

Re: To become a good C programmer (2011)

#86
I think for us laymen, the most difficult thing is to find a good reason to use C frequently. I have a few "legitimate" (in the sense that C is actually suitable for those) non-embedded projects that I'd like to take on in the future when I have time to pick up C:

1 - Recreate some of the Linux command line tools, including a command line interface similar to BASH;

2 - Implement a fully functional compiler or byte-code Virtual Machine for a stripped down scripting language;

3 - Write a key-value data store

Sadly I really can't name any project that is not system programming. I saw some projects that use C for backend (CGI style?) programming or game programming but I believe there are more suitable tools for either of them.

BTW I also found it very clear to use C or a stripped down version of C++ to teach myself Data structure.

Re: To become a good C programmer (2011)

#87
>> Expert C Programming . This book is fantastic because it will bring your attention to what happens under the hood in a very entertaining way. I am not a C programmer nor was trying to become one. Just trying to be familiar with low level programming and computer internals in general. But I enjoyed reading the book a lot. One of the the stories I remember is about the programming contest at Carnegie-Mellon University. The rules were simple that the program had to run as fast as possible and the program had to be written in Pascal or C. Here are some paragraphs extracted from the book about the result. “The actual results were very surprising. The fastest program, as reported by the operating system, took minus three seconds. That's right—the winner ran in a negative amount of time! The next fastest apparently took just a few milliseconds, while the entry in third place came in just under the expected 10 seconds. Obviously, some devious programming had taken place, but what and how? A detailed scrutiny of the winning programs eventually supplied the answer. The program that apparently ran backwards in time had taken advantage of the operating system. The programmer knew where the process control block was stored relative to the base of the stack. He crafted a pointer to access the process control block and overwrote the "CPU-time-used" field with a very high value. The operating system wasn't expecting CPU times that large, and it misinterpreted the very large positive number as a negative number under the two's complement scheme. “

Re: To become a good C programmer (2011)

#88
post #30

Earlier quoted context omitted.

The names in stdint.h are ok, but the way they play with library functions like printf() and scanf() is not so great. Given an int64_t value x, each of these works on some platforms and is wrong on another: printf("here's your int64_t: %ld\n", x); printf("here's your int64_t: %lld\n", x); And the portable way using inttypes.h is really ugly: printf("portably int64_t: %" PRId64 "\n", x); There's another religious argu…

Then there’s the perennial problem of missing format specifiers for POSIX types like pid_t. Although you could argue that POSIX should mandate macros to appropriately handle them, the root problem is the same. The default integer types have not aged well...

> missing format specifiers for POSIX types like pid_t

This bothers me less because I can always cast it up:

    fprintf(logfile, "pid: %lld", (long long)pid);
Technically not portable, but find a platform with PIDs where this breaks. You can count on long long being at least 64 bits, and I think it'll be a while before we need 128 bit process IDs. :-)

> The default integer types have not aged well...

To me, the real pisser is that every compiler copped out and decided to leave int at 32 bits when the architecture advanced to 64 bits. Part of the reason for compilers exploiting "signed can't overflow" is so they can work around for loops with 32 bit int variables, and this has ugly consequences because most of the conversion rules in C are defined with respect to int.

And honestly, Microsoft should burn for leaving long at 32 bits.

Re: To become a good C programmer (2011)

#89

One of the things I tend to think about these days is return on investment. I spent several years at the beginning of my career being a bad and then mediocre C programmer, and once I found a few other languages, I got the sense that being a mediocre-to-good programmer in these languages would be much easier, and that seems to have been borne out. Late into a career investing in other areas, what's the advantage of be…

Rust isn't viable for embedded platforms, at least not yet. It's not as easy to compile it to the most obscure ISAs as C, and the little support it has for stuff like STM32 is restricted to just that group of microcontrollers and doesn't support the entire ARM range. Maybe in the future? I'm looking forward to that day! Go is probably never going to run on microcontrollers due to its very big overhead. C perfectly ma…

While it is true that C perfectly matches the hardware, it imperfectly matches the rich software abstractions which are needed for moderate and large software. The lack of namespaces, sane object creation, destruction features etc, makes programming tedious. A large proportion of code in many large C programs go into recreating imperfectly the features that are by default provided by richer programming systems, and that repeats for every large program you do. It quickly becomes boring and unenlightening, to recreate an exception handling mechanism or data structure implementation for the nth time. Why would anyone not prefer not having to focus on the mere infrastructure, and rather direct directions on the interesting problems to be solved.

Another thing is that large C code bases tend to become ensconced in layers of preprocessor macros, which I think is a hack-y way of doing things.

Re: To become a good C programmer (2011)

#90

One of the things I tend to think about these days is return on investment. I spent several years at the beginning of my career being a bad and then mediocre C programmer, and once I found a few other languages, I got the sense that being a mediocre-to-good programmer in these languages would be much easier, and that seems to have been borne out. Late into a career investing in other areas, what's the advantage of be…

Oh come on now. I will develop in "safe" languages where possible (my favorites are F# and Erlang), but when I need to do something on the hardware, I still use C (and C++). Rust and Go are not viable options for everything, especially when you need complete control.

Why does the Rust community have to make every discussion about Rust?

Post reply on HN