Live data from Hacker News

Principles for C programming

drewdevault.com

111–120 of 149 posts

Re: Principles for C programming

#111
post #97

Earlier quoted context omitted.

Yes, I think typedefing scalars is fine. Typedefs are useful for abstracting the underlying storage mechanism for a scalar (so you can i.e. change it on different archictures or in a future release without breakage), not for saving yourself 6 characters of typing.

Typedefs are useful for creating short-hand names for otherwise long or complicated type definitions. Saving 7 (6 for 'struct' + space) characters is as good use for typedef as any other.

You only have to write each set of seven characters once; yes, typing will require a bit more effort. However, we shouldn't optimize code for the ease of writing, we should be optimizing for the ease of reading. Write once, read many.

`struct foo` is a bit more instructive when understanding code than `foo`; at worst, they read the same to someone familiar to the codebase, at best they prevent the need to flip back and forth to the type definitions.

Re: Principles for C programming

#112

Earlier quoted context omitted.

Not sure I follow. > scalars So you would typedef the scalars then? If you don't, then scalars will be the built-in types (which you'd presumably know well) and then all other type names will be typedef'ed structs/unions, still making it trivial to recognize them as such.

Yes, I think typedefing scalars is fine. Typedefs are useful for abstracting the underlying storage mechanism for a scalar (so you can i.e. change it on different archictures or in a future release without breakage), not for saving yourself 6 characters of typing.

You can just use stdint types. Or is it really better to typedef a CUTE_INT?

Re: Principles for C programming

#113

I've recently been reading Scott Meyers' Effective (Modern) C++ books. They are fantastic - can anyone recommend something similar for C? I.e. books that assume you're familiar with the language, but explains pitfalls and best practices in a practical way.

21st Century C is very very good.

http://shop.oreilly.com/product/0636920033677.do

Enjoyable to read through, covers tools as well as the language, and a very good reference of good practise. It covers the basics and then goes into depth on a few of the things C is supposed to be bad at, demonstrating good ways to work (strings, threads, OOP, libraries).

I have a copy on my bookshelf at work, and have been referring to it extensively this week (exposing a C entry point to a C++ world...) It has steered me away from some fairly silly things a couple of times!

It does disagree quite strongly with the article though.

Re: Principles for C programming

#114

Earlier quoted context omitted.

> Do not use macros. Sir, yes, sir. I will throw away "offsetof" and "container_of" right now, just give me a moment. > Do not use a typedef to hide a pointer or avoid writing “struct” Somewhat agree with the former, but completely disagree with the latter. If there's a single thing that is not right with C is its excessive verbosity in places where none is needed. Not typedef'ing your structs forces you to use extra…

>Not typedef'ing your structs forces you to use extra 7 characters per type mention for no clear benefit. To put it differently - if NOT having "struct" in front of a type name has any effect on readability/maintainability of your code, then there are deeper problems with your coding style that won't be solved by dragging "struct" around. The benefit is to readability. You should treat structs differently from scalar…

Why not pass structs by value?

Of course, it is copied because "by value". On the AMD64 architecture your compiler will transfer your little structs in registers.

Re: Principles for C programming

#115
post #76

1) Learn Compiler Design 2) Write a Compiler for a better language 3) In new language, write a compiler for your new language 4) Retire from C programming, occasionally come to Hacker News to reminisce about C programming and ways to avoid shooting yourself in the foot

Fortunately, Walter Bright did that. Now I can simply use his language to retire from C to D. :)

Re: Principles for C programming

#116
post #23

Earlier quoted context omitted.

I tend to find fixed size buffers easier to conceptualize than dynamically allocated buffers. Tend to find that even with most modern language C#/Java I still see developer use fixed size buffer even within enterprise apps. So I think there is something to be said with the whole movement of books/expert advice advocating against fixed size buffers/enum's to use more dynamic memory models when people in the trade are…

> even within enterprise apps. The epitomes of today's software. I really like how you used "even".

Worked on a number of different projects clearly from a maintence perspective. From C,C++ mostly around VBS2/VBS3 (Operation Flashpoint) and VSS Simulation systems. Moved on from C/C++ simulation market when the money wasn't really in it unless you're the sales people or upper management. Kind of drives it home when you bike into work and all management are driving BMW ect.. This was a startup that I took a major pay cut.

After that phase moved into web development. Tomcat/Java and Servlet containers and C# and F#. I've spent about in total 12 to 15 year's software development in this field.

When I first started programming I learnt from Quake/Doom Engine from John carmack. I can attest his software style and technical finesse was something to be admired even to me today. There was something to be said to have a look at good written C code that was really straight forward and easy to follow. At this time OOP/Java was starting to become a mainstream in the market place and most of hype and push was from marketing and also compiler writers/contracts wanting to push their contracting sales pitch at Universities/Schools and management.

Granted the whole OOP/Java was one giant experiment that paid off for other people but never really paid off for me. In my younger years I remember not getting OOP. When I say NOT getting it, I never really felt there was a clear explanation of what OOP was and my gut feeling was the whole theory vs practicality didn't work for me. So seeing that I had to time to waste I started research and reading as many OOP books as I could find. In total I've read about 60 different OOP books and research papers. After all this I still conceptually don't GET OOP. The whole thing a act in cognitive dissonance for me.

You probably GOT OOP but I never did. So more power to you.

My only anecdotal (Single data point) experience has been maintaining a large range of different type of software over the years. From procedural code, to functional programming all the way Java, and Spring (Inverse Version Control).

A lot of smart people than me in in the 90's/2000 created these massive taxonomy systems. Multiple inheritance from anything from 10 to 15 layers deep. Excessive use of design patterns and over-use of meta-programming where meta-programming (really) didn't need to be used all the time (look at you C++). I remember night tearing my hair out because these things TOOK up the fucken wall. Litterally the taxonomy's was just that large that had so many inter-layered derived class calling Derived classes that called in turn called the base classes then would in turn call the Derived classes, that would then in turn call some event handler. Yes you get the picture.

It did take about 3-4 years of 10 hour nights to finally get this massive inheritance system (Operation Flashpoint btw) where you could be productive. Then two months after I quit.

I then moved over to Java, and web-app development. Where I doubled my wage overnight. The Java project's designs had also drunk the kool aid also during the 2000's. So yet again I was faced with 7 to 8 layer (Single) inheritance system. Each consecutive developers building on this inheritance system. As you can imagine, the cost/turn around time and budget for such a system caused then to drop the system. They settled on Spring and dependency inversion control.

Granted most of the code I see teams writing is a throw back to procedural code. You have your controller that processes requests that in turn passes it off to services. That in turn accesses Repositories. This is inclusive of your typical MVC model, but most of the services, and code now I see is just a singleton instance of the class that just acts as a namespace for functions.

Prior to this in java land, all enum's and statically allocating arrays where bad and unclean. DIK_CODE's or id identifiers where discarded into the rubbish. Replaced by developers using inheritance type system to replace such crude (primitive) approaches of programming! Looks at all those enum's lets replace them using the type system of the language!

So for example instead of writing.

#define CUSTOMER_PAGE 1

#define CUSTOMER_CHECK_OUT 2

#define ORDER_FORM 3

You had developers using the type system in its replacement.

class Validator impliments IValidator

class Orders extends Validator

class CustomerPage extends Orders

class CustomerCheckOut extends Orders

class OrderForm extends CustomerPage

Somebody is going to come here and proclaim `they were doing it wrong`. I just shrug my shoulders and say it doesn't really matter I'm stuck looking at this mess.

For today, I see developer and new projects coming online where they've moved away from such inheritance model's and moved to a more procedural approach and flat design. I do welcome this move, and cheer for the faster turn around time.

It takes me on average when faced with new projects that use massive inheritance structure's 4-5 days to get my head around the system (If at all). The same or more complicated systems using procedural old statically defined array, enum's and defines take about 1 hour to find and isolate the problem and fix.

Other teams may have had success with large scale OOP code-bases. Though I've mostly found them to be error prone, more riddled with edge case situation and bugs. They're a nightmare to extend (counter to the whole notion of the sole reason for OOP), than your typical on this ID do this approach. It's something to be said I've recently started doing development work on mmpeg and x264 code base and its a please to be up to speed and doing some productive work within 2 to 3 hours.

Re: Principles for C programming

#117
post #76

1) Learn Compiler Design 2) Write a Compiler for a better language 3) In new language, write a compiler for your new language 4) Retire from C programming, occasionally come to Hacker News to reminisce about C programming and ways to avoid shooting yourself in the foot

Writing a compiler in C that can compile it's source code is for me, the best thing to do before retiring from C programming.

Re: Principles for C programming

#119
post #80

Earlier quoted context omitted.

> They are "protected", yes, but their mere presence encourages people to use them. There's no reason to use asprintf, but glibc makes it available so some software uses it. That software is now non-portable. I think asprintf is useful - it replaces an ugly "malloc-realloc-snprintf-loop"... On exposing non-portable functions/features: - OpenBSD does it (pledge) - Freebsd/NetBSD do it (kqueue) - ... I'm certain other…

>I think asprintf is useful - it replaces an ugly "malloc-realloc-snprintf-loop"... Well, implement it yourself then. It's really not hard to live without, though. I don't know about this loop you're talking about but I just do this: int len = snprintf(NULL, 0, "fmt", ...); char *foo = malloc(len + 1); snprintf(foo, len, "fmt", ...); Easy to wrap that up in your own asprintf function if you would find that useful. An…

I did not know that the return value of snprintf is actually the length of the string that would be produced. I assumed I'd just get some error code - which would require re-trying with some larger buffer, thus the "loop".

Thanks for that :-)

Re: Principles for C programming

#120

Earlier quoted context omitted.

This should have been shorten to "Avoid magic". This is applicable to any language, not just to C. Magic stuff are for wizards, and most of us are not.

"Magic" becomes obvious common-sense once you understand. The overall theme of the parent comment is that we should try to understand instead of giving up, because that's what makes us learn and become better at the language. IMHO if you want to become an expert in C and C++, you must be able to read Asm and understand what the machine is actually doing. A very relevant article on this same idea: http://www.linusakes…

> "Magic" becomes obvious common-sense once you understand.

I fully agree. Packing data into a binary array, popcount with bit fiddling, macros for generics, etc may seem "magic" to some, but they can be useful especially in performance-critical code. Once you understand these "magic", they are just some common pieces in your toolbox. C is a simple language. Learning C plus such "magic" still takes much less time than grasping the entire C++.

Post reply on HN