Live data from Hacker News

Principles for C programming

drewdevault.com

61–70 of 149 posts

Re: Principles for C programming

#61
> GNU is a blight on this Earth, do not let it infect your code.

Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

Re: Principles for C programming

#62
post #61

> GNU is a blight on this Earth, do not let it infect your code. Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

I think the author meant specifically GNU extensions to various POSIX functions, which can be a pain when trying to run code using them in non-GNU environment.

Re: Principles for C programming

#63
I'll wade in a little.

> Don't use macros.

> Don't use the inline keyword

> Never put code into a header

I disagree with these. It's often critical to avoid a function call in hot paths, and if you don't use macros or inline you have to resort to copy/paste, which is error-prone and hampers maintainability.

It's also the case that C is a rather inflexible language. Macros can be extraordinarily helpful in reducing boilerplate: in unit testing, for example. I won't argue that macro definitions are the easiest things to read (usually they're OK but they can get pretty arcane), but I do think something that cuts a file down from 8,000 lines to 1,000 is at least worth considering.

Macros can also help you maintain type safety. Colin Perciva demonstrated this a little with his elasticarray, but khash is another example of using macros to dynamically create type safe data structures. It can also help the compiler optimize your code.

> Don't use fixed-size buffers

Everything is a fixed-size buffer until you change its size. If you malloc a buffer of 1024 bytes and read 1025 bytes of user input into it, you overflowed anyway. The principle ought to be "check your bounds", which applies whether your buffer is stack/heap.

> Do not use a typedef to hide a pointer or avoid writing “struct”.

I'm with you on pointer hiding (looking at you FreeType), but "struct" is just far too verbose. You don't accidentally pass things by value because the compiler will tell you you're passing the wrong type. You won't think it's actually a scalar because you have a grand total of 3 scalars in C (bool/int/float), and if you don't know the types you're working with in your functions you should probably look them up.

You probably don't think this is a big issue because you don't adhere to 80 columns in your code (I looked @ your GitHub briefly), but let me tell you you run out of space real quick, and "struct" is practically meaningless.

I found a good example:

  static void set_background(struct wl_client *client, struct wl_resource *resource,
  		struct wl_resource *_output, struct wl_resource *surface) {
vs.

  static void set_background(wl_client *client, wl_resource *resource,
                                                wl_resource *_output,
                                                wl_resource *surface) {
These are obviously not ints, it's a lot easier to read, and it fits in terminals. "struct" is honestly just noise.

> GNU is a blight on this Earth

Come on now. I hate GNU indentation as much as any reasonable person, but I don't think we need to go this far.

---

Unrelated: aerc looks great! I've been thinking about moving off gmail and moving more of my life back into the terminal (I used to be all mutt and IRC and now I'm gmail and hangouts :/ ), and I really like aerc's well-organized code. Nice work.

Re: Principles for C programming

#64

> Use only standard features. Do not assume the platform is Linux I'll decide what platform I am targeting, thank you. I don't feel any obligation to support obscure OSes if I am just targeting linux. I might as well use useful linux-specific and GNU userland features, they are helpful.

"Do not assume" doesn't really mean or imply "do not target", so stop being defensive. It's good advice.

Re: Principles for C programming

#65
post #61

> GNU is a blight on this Earth, do not let it infect your code. Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

It's "All the world's a VAX" in its new form, where you depend on some language/library feature that's actually not in the standard (IIRC alloca and preprocessor extensions are common culprits).

And then suddenly you're on a different platform and discover that you can't rely on that -- pretty bad if it's in a central part of your system (like trampolining functions for your toy lisp).

On the other hand, you might run into the same issues if the standard support is sub par. People used to declare K&R-style functions for ages after ANSI was passed, and I wouldn't bet a central part of my system on C99.

Re: Principles for C programming

#66
post #62
post #61

> GNU is a blight on this Earth, do not let it infect your code. Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

I think the author meant specifically GNU extensions to various POSIX functions, which can be a pain when trying to run code using them in non-GNU environment.

Yes, that is a good point.

However I thought that "blight" implies some actual technological inferiority. If there is some, I would like to know more about that.

Re: Principles for C programming

#67
post #65
post #61

> GNU is a blight on this Earth, do not let it infect your code. Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

It's "All the world's a VAX" in its new form, where you depend on some language/library feature that's actually not in the standard (IIRC alloca and preprocessor extensions are common culprits). And then suddenly you're on a different platform and discover that you can't rely on that -- pretty bad if it's in a central part of your system (like trampolining functions for your toy lisp). On the other hand, you might ru…

So in your opinion the problem is "only" one of portability to non-gnu systems?

I thought the author also implied that GNU was technologically inferior and/or problematic. That would interest me...

Re: Principles for C programming

#68
post #61

> GNU is a blight on this Earth, do not let it infect your code. Can someone explain this sentiment to me? I know about licensing and philosophical criticisms, but are there any _technical_ faults?

Lots of GNU code flies in the face of these principles. A lot of GNU software encourages bad behaviors like using non-standard features (which makes for non-portable software). GNU software is also often very bloated and overengineered, and often found in critical places like glibc. Their coding styles are highly questionable and I disagree with a lot of their design decisions.

Re: Principles for C programming

#69

Earlier quoted context omitted.

Just take an 'i' or 'f' or 'l' on the end. Not a big deal. Literally one extra character. I don't think you understand. At a minimum, you would need parsenumi, parsenuml, parsenumll, parsenumimax, parsenumu, parsenumul, parsenumull, parsenumumax, parsenumi8, parsenumi16, parsenumi32, parsenumi64, parsenumu8, parsenumu16, parsenumu32, parsenumu64, parsenumf, and parsenumd. All code is liable to use an outdated syntax…

>I don't think you understand. At a minimum, you would need parsenumi, parsenuml, parsenumll, parsenumimax, parsenumu, parsenumul, parsenumull, parsenumumax, parsenumi8, parsenumi16, parsenumi32, parsenumi64, parsenumu8, parsenumu16, parsenumu32, parsenumu64, parsenumf, and parsenumd. Fair. I still don't really see the value in this, though. The only real gain is from doing the range check, and that's niche enough th…

that's niche enough

Not niche at all. You should have a range check on pretty much every value you accept from a command-line option.

Re: Principles for C programming

#70
post #50
post #38

Earlier quoted context omitted.

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

The reality is that if you are creating a library you probably should prefix your types and functions anyway. And rely on the prefix to minimize collision probability. So it doesn't really matter if you put _t and the end of your type aliases. You will probably not get the collisions anyway. Unless POSIX is going to suddenly introduce mylib_array_t or something.

No, but your compiler MIGHT decide in a future release that it's a whole lot faster to ignore the header files for standards types and definitions and just copy a pre parsed version of the struct into the symbol table when the header is included. It might look at the _t and decide nope, I don't have a definition for this so it's an error, despite your own definitions.

This probably won't happen. But if it does you don't have any grounds for complaint really.

Post reply on HN