Live data from Hacker News

Principles for C programming

drewdevault.com

31–40 of 149 posts

Re: Principles for C programming

#31

>Do not use macros. Do not use a typedef to hide a pointer or avoid writing “struct”. Avoid writing complex abstractions. Keep your build system simple and transparent. Don’t use stupid hacky crap just because it’s a cool way of solving the problem. Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros…

> 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 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.

Re: Principles for C programming

#32

>Do not use macros. Do not use a typedef to hide a pointer or avoid writing “struct”. Avoid writing complex abstractions. Keep your build system simple and transparent. Don’t use stupid hacky crap just because it’s a cool way of solving the problem. Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros…

Also, typedef make things like arrays of function pointers much easier to read.

Re: Principles for C programming

#33

Avoid magic. Do not use macros. Disagree. Use magic, especially macros, in ways such that your code becomes easier, not harder, to understand . A few examples from my own code: 1. My "elastic arrays" ( https://github.com/Tarsnap/libcperciva/blob/master/datastruc... and .c) allow me to write ELASTICARRAY_DECL(STRLIST, strlist, const char *); and get a data structure STRLIST which contains an arbitrary number of string…

>1 I'm conflicted about this one. I choose not to try and emulate generics with macros because adding language features with macros is a terrible idea. On the other hand, I recognize the problem with void*. It's a matter for debate but I definitely fall on the "don't use macros for this" side. >2 This is a case where I would rather write more code than rely on magic. You have to have this awful hacky opaque implement…

#define IT "I think" // :)

>2 IT the swicth/cases are quicker/clearer to grasp than the one with BIGMACROS_X

>4 IT you shouldn't underestimate the existing neural paths of knowledge of stdlib for C devs. those std functions are read / parsed almost intuitively, unlike cute macros, except for their creator.

I'am ll for "cleaning" C and have a non-completely backwards dependent / improved standard, but I'd much prefer strtof than a custom macro. And those standard C functions are often accelerated to death by compilers (see: memcpy by example).

Re: Principles for C programming

#34
post #10

Earlier quoted context omitted.

I guess there are 'donts' because people need help with the keep it simple part, they are quite comfortable with the stupid part.

"nobody's grading your code by how many abstractions and topics from a textbook it employs."

That said, people sometimes ate grading your code based on performance. Good algorithms often win over simplistic ones.

Re: Principles for C programming

#35
post #32

>Do not use macros. Do not use a typedef to hide a pointer or avoid writing “struct”. Avoid writing complex abstractions. Keep your build system simple and transparent. Don’t use stupid hacky crap just because it’s a cool way of solving the problem. Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros…

Also, typedef make things like arrays of function pointers much easier to read.

It all depends on the level. array of pointers to func to array of structs X , yes. struct X, no.

Re: Principles for C programming

#36

Avoid magic. Do not use macros. Disagree. Use magic, especially macros, in ways such that your code becomes easier, not harder, to understand . A few examples from my own code: 1. My "elastic arrays" ( https://github.com/Tarsnap/libcperciva/blob/master/datastruc... and .c) allow me to write ELASTICARRAY_DECL(STRLIST, strlist, const char *); and get a data structure STRLIST which contains an arbitrary number of string…

>1 I'm conflicted about this one. I choose not to try and emulate generics with macros because adding language features with macros is a terrible idea. On the other hand, I recognize the problem with void*. It's a matter for debate but I definitely fall on the "don't use macros for this" side. >2 This is a case where I would rather write more code than rely on magic. You have to have this awful hacky opaque implement…

Just use strtol or strtof

Which of these is more likely to have bugs?

    int i;
    
    if (PARSENUM(&i, s, 0, 1000))
        err("Invalid input: %s", s);
or

    int i;
    long l; // need a temporary long to avoid overflow
    char * ep;
    
    errno = 0;
    l = strtol(s, &ep, 0);
    if ((ep == s) || (*ep = '\0'))  // make sure we parsed a number and don't have trailing garbage
        errno = EINVAL;
    if ((l  1000))
        errno = ERANGE;
    if (errno)
        err("Invalid input: %s", s);
    i = l;
You build these esoteric systems that use heaps of unmaintainable, unreadable code

Not at all. The point is to have self-contained routines which Just Work in order to ensure that the rest of the code is easier to read and maintain.

Re: Principles for C programming

#37

Avoid magic. Do not use macros. Disagree. Use magic, especially macros, in ways such that your code becomes easier, not harder, to understand . A few examples from my own code: 1. My "elastic arrays" ( https://github.com/Tarsnap/libcperciva/blob/master/datastruc... and .c) allow me to write ELASTICARRAY_DECL(STRLIST, strlist, const char *); and get a data structure STRLIST which contains an arbitrary number of string…

As a webdeveloper that likes to use C rarely for private things: I like that "elastic arrays" thing.

Feel free to use it. All of the libcperciva code is BSD licensed and should build and work on any C99-compliant system.

Re: Principles for C programming

#38

I disagree with quite a few of them. The title should be "Principle for C programming ON UNUX BASED SYSTEMS". C programming is quite a bit wider that this, and some of the typical points here are no-no if you want to write /portable/ C. For example, "Do not use fixed size buffers". It's all very fine, but 1) it can be exploited as well if someone managed to fudge the size you are going to allocate, and 2) on some pla…

> 'I typedef my structs all the time, and call them something_t, and * something_p’

I wish people would stop perpetuating this particular naming convention. Its in violation of POSIX which specifically reserves the entire *_t ‘namespace’. Obviously its fine if this is done on a system or environment for which this is irrelevant, but its best avoided otherwise.

Re: Principles for C programming

#39

>Do not use macros. Do not use a typedef to hide a pointer or avoid writing “struct”. Avoid writing complex abstractions. Keep your build system simple and transparent. Don’t use stupid hacky crap just because it’s a cool way of solving the problem. Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros…

> 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 scalars, and the code should make the distinction apparent. You should not generally, for example, pass structs by value. This is just laziness.

Re: Principles for C programming

#40
post #23

Earlier quoted context omitted.

It's quite common in Embedded programming to use pools of fixed size buffers. Malloc/free work on these pools.

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".

Post reply on HN