Live data from Hacker News

My personal C coding style as of late 2023

nullprogram.com

211–220 of 466 posts

Re: My personal C coding style as of late 2023

#211

i love this blog, i hold Chris Wellons to a very high estime BUT i utterly disapprove the usage of macros so much, especially to wrap cstd types, functions, etc.

I'm currently on a C++ (mostly C with C++ compiler) trip. It does make some things easier and some things harder. It makes it easier to work with C++ developers :-). I sometimes use the more involved C++ features but often regret it after because of complications.

But one thing that makes it worth it is the removal of the struct tag space. I have a strong dislike for the struct tag boilerplate in C, but the alternative -- typedef boilerplate -- in C is unbearable to the point that I have a macro to define structs in C that does this automatically.

    #define STRUCT(name) typedef struct name name; struct name

    STRUCT(Foo) {
        int x;
        int y;
    };
But macros often come with disadvantages. In this case it's that many IDEs have trouble finding the struct definitions from a usage site.

Re: My personal C coding style as of late 2023

#212

> #define countof(a) (sizeof(a) / sizeof(*(a))) > #define lengthof(s) (countof(s) - 1) It makes no sense to use the word "length" to mean one less than the number of items. You could call it maxindexof perhaps. There may be good arguments for zero based indexing, but we have to also accept that there are downsides. One is that your code has to feature an artificial quantity obtained by subtracting one from a meaningf…

This is length of a null-terminated string, e.g. lengthof("abc").

Re: My personal C coding style as of late 2023

#213
post #191

Why would anyone care what the favorite whatever style of some dude on the Internet is? I like petunias! Now what? How does that help anyone?

Your preference doesn't help anyone. That's true. But coding styles may improve its reader's programming.

Re: My personal C coding style as of late 2023

#214
post #186

IMO, defining your own types is one step too far. Now everyone who is already familiar with C types has to learn your own quirky system to understand one program. I think it does probably make sense to be specific about the sizes though e.g. using uint32_t over just uint (and expecting to receive some architecture-dependent size you might not get with uint.) These types should be defined in the right header (I think…

> These types should be defined in the right header stdint.h It's always been amazing to me how many different projects I've worked on (not that I've been in professional C for about 7 years now)) that include their own painstaking recreation of this file. Reusing them and effectively translating them just to your own name is just annoying to the reader IMHO. I am reminded of a C++ project I worked on, where I questi…

For bool it's even worse.

Re: My personal C coding style as of late 2023

#215

IMO, defining your own types is one step too far. Now everyone who is already familiar with C types has to learn your own quirky system to understand one program. I think it does probably make sense to be specific about the sizes though e.g. using uint32_t over just uint (and expecting to receive some architecture-dependent size you might not get with uint.) These types should be defined in the right header (I think…

The reality is that C `int` is 32 bits in size. Sure, that's not true for 16 bit targets. But are you really going to port a 5Mb program to 16 bits? It's not worth worrying about. Your code is highly unlikely to be portable to 16 bits anyway. The problem is with `long`, which is 32 bits on some machines and 64 bits on others. This is just madness. Fortunately, `long long` is always 64 bits, so it makes sense to just…

Yet another issue is that `char` is signed on some platforms but unsigned on others. It is signed on x86 but unsigned on RISC-V. On ARM it could be either (ARM standard is unsigned, Apple does signed).

I therefore use typedefs called `byte` and `ubyte` wherever the data is 8-bit but not character data. I also use the aliases `ushort`, `uint` and `ulong` to cut down on typing. On the other hand, the types in are often recognised by syntax colouring in editors where user-defined types aren't.

Re: My personal C coding style as of late 2023

#216
> While I still prefer ALL_CAPS for constants, I’ve adopted lowercase for function-like macros because it’s nicer to read.

"ALL_CAPS" in C was not for constants, but for preprocessor macros. It's shouting in all-caps, because it means "Look out! There's a cpp macro expansion here!"

Related, please stop using "ALL_CAPS" for constants in other languages. Not only does shouting constants as the most prominent syntax in the code make no sense, but there are much better uses for shouting in a programming language.

(For an example of a good use of "ALL_CAPS": if your language ever acquires Scheme-like template-based hygienic macro transformers, "ALL_CAPS" (or "ALL-CAPS") is excellent for making template pattern variables stand out within the otherwise literal code blocks.)

Re: My personal C coding style as of late 2023

#217

IMO, defining your own types is one step too far. Now everyone who is already familiar with C types has to learn your own quirky system to understand one program. I think it does probably make sense to be specific about the sizes though e.g. using uint32_t over just uint (and expecting to receive some architecture-dependent size you might not get with uint.) These types should be defined in the right header (I think…

The big issue with custom integer types is that while they are awesome in the implementation files, they are problematic for libraries in headers. And if you want to avoid a divergence between header and implementation files you're kinda stuck with the inttypes.h ones in practice.

Re: My personal C coding style as of late 2023

#218

I might just be a grumpy old dev but a lot of this stuff gets an immediate no from me because it’s so unidiomatic. You have to unlearn the accepted way of doing things and you end up with a codebase that is just so foreign to anyone looking at even a small chunk of it, unless they are committed to really learning to do things your way. Everyone knows what a uint32_t is when they see it. The cognitive overhead (until…

Unpopular opinion: something being unusual does not necessarily mean it is bad. Yes, it will look foreign to random people looking at it, but if someone wants to seriously work with it, it will only take a few days to get familiarised with it. The justification of "cognitive overhead" is, from what I have seen, a shibboleth for rejecting "outsider" code written by someone not conforming to the language standards by c…

Well said. This is also something that I don't buy from the criticism towards Lisp. Something along the lines of: "Lisp did not become mainstream because everyone writes their own little language for their project, and so no one can understand other project's code."

pg wrote excellent arguments against this criticism in "On Lisp" § 4.8 Density, which apply just as well to the discussion above:

    “If your code uses a lot of new utilities, some readers may complain that it is hard to understand. People who are not yet very fluent in Lisp will only be used to reading raw Lisp. In fact, they may not be used to the idea of an extensible language at all. When they look at a program which depends heavily on utilities, it may seem to them that the author has, out of pure eccentricity, decided to write the program in some sort of private language.

    [...]

    If people complain that using utilities makes your code hard to read, they probably don’t realize what the code would look like if you hadn’t used them. Bottom-up programming makes what would otherwise be a large program look like a small, simple one. This can give the impression that the program doesn’t do much, and should therefore be easy to read. When inexperienced readers look closer and find that this isn’t so, they react with dismay.”

Re: My personal C coding style as of late 2023

#219

Earlier quoted context omitted.

> carrying bit length in the name is critical I beg to disagree. In D: byte - 8 bits short - 16 bits int - 32 bits long - 64 bits absolutely nobody is confused about this.

In that case D should probably start to have an internal conversation about what they're going to call 128 bits then, 'cause its going to become a thing sooner or later. stdint already has that covered though: (u)int128_t

it has defined the type for very long: it's cent and ucent. It hasn't implemented it completely though, but named and defined it is already forever.

Re: My personal C coding style as of late 2023

#220
post #71

typedef all structs - yes, helps with conciseness. Use typedefs liberally, I say. But only typedef the things themselves, not pointers to the things. You can always use (type *) when you need a pointer. In particular, for function pointers, typedef the function, not the function pointer. Then you can use the function typedef for function declarations too, which gives you parameter type checking without needing to fix…

I prefer to use typedef's for opaque structs to emulate classes with all private fields, and use 'struct' for plain ol' data structures. Classes should only be accessed via functions, while structs can be accessed directly. I think this is more-or-less a C/POSIX standard convention. E.g., `pthread_t` vs. `struct stat`.

It's definitely part of the linux kernel coding style: https://www.kernel.org/doc/html/v4.10/process/coding-style.h...
Post reply on HN