Earlier quoted context omitted.
I'm not a C developer, so I have to ask: why in the world would you not use const?
It's more work. Not only to put all the annotations correctly, but only because it causes some real headaches. It's easy (implicit) to transition from non-const to const 1 pointer level deep. But the other way around -- it's really awkward to "remove" a const. The strstr() signature is probably the shortest example / explanation why. To implement strstr(), you have to hack the const away to create the return value. A…
My personal C coding style as of late 2023
281–290 of 466 posts
Re: My personal C coding style as of late 2023
#282U1, U2, U4, U8, I1, I2, etc
Also S for "slot" aka unsigned pointer sized integer (usize_t)
Another big point is formatting code to line-up instead of with an autoformatter. When you are doing something which is almost the same but slightly different it helps readability considerably. It is also a sign of a well-loved codebase, since I've never seen an autoformatter that can do it.
Maybe we could make formatters at least auto _detect_ that code is already aligned and to just leave that code alone. Some kind of "love heuristic"
Re: My personal C coding style as of late 2023
#283Earlier quoted context omitted.
Yeah but not for basic types. Also, most code mingles sooner or later with other code. Than this is just ugly.
It’s better than dealing with needlessly long type names like uint32_t though
Re: My personal C coding style as of late 2023
#284Earlier quoted context omitted.
This is all very good and very, ahem, true. But (and it's a big butt); if (need_free == true) Is such a horrible code smell to me. You have a perfectly good boolean. Why compare it to a second boolean to get a third boolean? if (need_free) or if (!need_free) for the opposite case is so much better. I will admit that in my world this leaves if (need_free == some_other_bool) as something I don't have a particularly com…
> if (need_free == true) > Is such a horrible code smell to me. You have a perfectly good boolean. Why compare it to a second boolean to get a third boolean? > if (need_free) You are probably interested if the `need_free` flag is set to true, and not if `need_free`. It is true that `if (need_free)` has the same behaviour, but it is some steps farther from what you are interested in.
"You are probably interested in whether it's true that the 'need_free' flag is set to true"
leading to
> if ((need_free == true) == true)
? Answer: because that extra layer of indirection adds nothing, and just gives you a bit of extra cognitive load and an extra opportunity to make mistakes. I think the same is true about going from "need_free" to "need_free is set to true".
(This becomes less clear if you have variable names like 'need_free_flag'. I say: so don't do that then! It's almost always appropriate to give boolean values and functions that return boolean values names that reflect what it means when the value is true.)
Re: My personal C coding style as of late 2023
#285I would have used isize instead, I think.
Re: My personal C coding style as of late 2023
#286Earlier quoted context omitted.
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…
Isn't "int" 64-bit on some (rare) architectures?
Re: My personal C coding style as of late 2023
#287Earlier quoted context omitted.
For example, it would be illegal to do the following: > #define int long Because you're replacing the int keyword with something else. The standard says: > 17.6.4.3.1 [macro.names] paragraph 2: A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 3, or to the attribute-tokens described in 7.6.
That's C++. But I couldn't find the same restriction in C. In fact it seems that C allows it as long as you don't include any of the standard C header. > 7.1.2 "Standard headers" §5 [...] The program shall not have any macros with names lexically identical to keywords currently defined prior to the inclusion of the header or when any macro defined in the header is expanded.
Re: My personal C coding style as of late 2023
#288Earlier quoted context omitted.
> Wouldn’t existing programs just continue working? Only ones which don't have variables named `i8` or `b32` (which is common, but not for booleans). I've seen many projects which used the pattern [a-z][1-9]+ as variables. Those programs with a variable called `i8` won't compile if the standard made a type called `i8`. In particular, the standard reserves entire patterns to itself, so it cannot reserve the pattern of…
No program should every have variables names according to [a-z][1-9]+ pattern, except perhaps loop indices - and not even then.
Re: My personal C coding style as of late 2023
#289Honest question: why C? I've been writing C++ firmware for SoCs, supposedly an area where C is supposed to be king, and C++ was just as good, except it came with all the batteries included. So, why C?
> it came with all the batteries included Sometimes you do not want, or need, all the batteries.
Re: My personal C coding style as of late 2023
#290IMO, 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…
Just a note: defining own integer types has sense for resource-limited platforms. Most common type I see is something like "dim_t", which is 32-bit or 64-bit depending on use-case. 32-bit integers are often used even on 64-bit platforms in pointer compression schemes (for example, allocate your own heap and only store 32-bit offsets). This not only gives 2x improvement on memory usage for <4GB workloads, but it also…