5 ms·
Modular C: Reusable and Maintainable Code Using the C Language (1994) [pdf]
- deleted 7y ago[deleted]
- dktoao 7y ago"System programming differs from application programming in that system programming emphasizes performance over reusable and maintainable code" Maybe for sufficiently small systems. But on a large scale product (reusable and maintainable code == performance). Am I missing something. Seems like something one or our EEs would say to me to excuse their poor code quality
- SAI_Peregrinus 7y ago> Am I missing something Copyright 1994. C89 only, this predates C99... The year ought to be in the title.
- mistrial9 7y agono, that's not true.. in C, extracting struct elements into variables, holding temporary values for longer, explicitly adding intermediate steps in a dense reference of references, would be examples of 'optional' contents that help readability and lessen potential ambiguity to a human coder. Each time data moves, clock cycles are used, at least. For decades, compilers have looked for this sort of code and condensed it as an optimization, so the way the code is written is not always the way it executes at runtime, but the longer, verbose steps might add cycles, and therefore would be avoided when coding for 'systems performance'.
- WoodTree 7y agoOptimizing compilers are good at optimizing obvious code, so this usually isn’t a trade off. Many of the clever hacks you can find in books from the 80s are irrelevant now because the compiler can figure out what your naive code is doing and emit something optimized. Modern processors don’t even operate sequentially and will execute multiple lines in parallel when there are no data dependencies. For most code, the performance killer is when you try to be too clever or have too many pointer indirections. The compiler has a harder time with this, and is also precluded from applying other optimizations like auto vectorization, because it cannot figure out if it would change the meaning of your code. For true performance, you need to enter the land of intrinsics, manual vectorization, and cache-aware algorithms. Domains which very few engineers are qualified to work on. So just keep it simple and trust the compiler. This also applies to algorithms, complicated ones with lots of branching will often perform far far worse in practice than the naive one, you can’t trust the big-O alone. So profile when in doubt.
- drainyard 7y ago> So just keep it simple and trust the compiler. This also applies to algorithms, complicated ones with lots of branching will often perform far far worse in practice than the naive one, you can’t trust the big-O alone. So profile when in doubt. I've found that optimizing for cache is usually the biggest gain when trying to be clever with algorithms. Eliminating branches and being naive in the algorithm itself is usually a better idea than trying to be clever with special cases. In my experience.
- kccqzy 7y agoThis is old-fashioned (uses C89 instead of C99) and some of its "idioms" are questionable, like this one: list *p; list l = (list) malloc(sizeof(struct list)); l -> val = val; for(p = &the_list; *p && (*p) -> val < val; p = &((*p) -> next)) ; l -> next = *p; *p = l; Here p is a doubly indirect pointer and I would personally think this is an unwarranted cleverness. Furthermore this is the year 2019. Why would you still manually traverse a linked list? Oh right because C doesn't have parametric polymorphism (genericity) so you can't abstract out the traversal in a standard library. Consider the C++ equivalent (although I chose to use a doubly linked list for better reusability): list.insert(std::lower_bound(list.begin(), list.end(), val), val); See how the search for the location to insert is done by the library, and the insertion is also done by the library. This, to me, is truly reusable and maintainable code.
- badsectoracula 7y agoFWIW personally i prefer the C code. It is explicit at what it does, whereas the C++ one is harder to follow exactly what it does - and also very ugly (i never liked C++'s iterators). The double indirect pointer is hairy but at least everything you need to know to "parse" the code is right there.
- AnimalMuppet 7y agoIt depends on what you want. If you want to be able to see everything, then the C++ code is better. If you want to get the trees out of the way so that you can see the forest, the C++ code is better. And, for most of us, if you want to just write it and have it work, the C++ code is better. Sure, I might have to find an example of the iterator code in order to get the syntax right, but it's a lot easier to mess up the double indirect pointer code. Worse, when I mess up the iterator code, it likely doesn't compile. If I mess up the double indirect pointer code, it it likely to silently corrupt memory somewhere.
- jcelerier 7y ago> The double indirect pointer is hairy but at least everything you need to know to "parse" the code is right there. but why do you want to spend time parsing code that - does textbook-level things ? - has a thousand different places where a typo can end up - needs to be rewritten for every kind of list those are the red flags. Do you also go read your graphics driver's code when you push pixels to the screen ? > and also very ugly (i never liked C++'s iterators). ignoring the jump from what you like to a global assertion (the C version makes my eyes bleed), in C++ 20 you can also just do list.insert(std::lower_bound(list, val), val);
- xvilka 7y agoAt this point it's better just to convert the code into the proper modern programming language without all C drawbacks - Rust. Amazing c2rust[1] tool offers automated conversion[2] and refactoring[3] capabilities. It even allows you to script[4] the refactoring with Lua. All while preserving ability to run and (probably) pass the tests. [1] https://github.com/immunant/c2rust https://github.com/immunant/c2rust [2] https://c2rust.com/manual/quickstart.html https://c2rust.com/manual/quickstart.html [3] https://c2rust.com/manual/c2rust-refactor/index.html https://c2rust.com/manual/c2rust-refactor/index.html [4] https://c2rust.com/manual/c2rust-refactor/doc/scripting_api.html https://c2rust.com/manual/c2rust-refactor/doc/scripting_api....
- zik 7y ago> the proper modern programming language I understand wanting to advocate for your favorite programming language but this kind of elitist attitude doesn't do the cause any favors, it's more likely to turn people away than anything. Rust is not "the proper programming language". It's just one of many excellent choices.
- ajxs 7y agoYou're absolutely right. These people have seriously marred my view of the language.
- deleted 7y ago[deleted]
- 0xdead 7y agoHere comes the guy everyone was expecting.
- euske 7y agoLooks like this is written in TexInfo. Is there a HTML version or the texi source available?
- a3n 7y agoThe table of contents is the last three pages. (Is that normal within some community?)