Live data from Hacker News

My personal C coding style as of late 2023

nullprogram.com

441–450 of 466 posts

Re: My personal C coding style as of late 2023

#442

Can anyone explain the use of ptrdiff_t instead of size_t (he has typedef'd "size" for ptrdiff_t) The macros are wrapping _Alignof and sizeof both which can't return non-zero numbers I thought.

ptrdiff_t is a signed integer type - which means you can subtract these numbers without worrying about underflow

Re: My personal C coding style as of late 2023

#443

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…

Oh I don't even know where to start with this. Given that C is the lingua franca of embedded development, and each processor and compiler has different opinions of what an int is, I would never claim that an int is 32 bits.

It's just so much less error prone to define a uint32_t. That's guaranteed to be the same

Re: My personal C coding style as of late 2023

#444

Earlier quoted context omitted.

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…

Default signed/unsigned is not a platform convention but a compiler one. You can change it with a compiler switch, in the makefile.

"might" be able to change it. It's fine in GCC based compilers, but some awkward/old compilers don't give you the luxury

Re: My personal C coding style as of late 2023

#445

Earlier quoted context omitted.

What's the point of the `k` prefix?

k for konstant

IMHO that’s much uglier than using caps.

Sometimes when I use C++, I will namespace them however:

    namespace constants {
        static constexpr int name = 42;
    }
    …
    int x = constants::name;
The exact name of the namespace would depend on the use and could be something more descriptive.

Re: My personal C coding style as of late 2023

#446

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…

You can just #include to get those types, at least in the environments I’ve worked in.

Re: My personal C coding style as of late 2023

#447

I disagree about the structs vs out-parameters thing. I’ve found it makes functions that could return an error much harder to compose and leads to a proliferation of types all over the place. In practice almost all functions can fail (assuming you are handling OOM), so having a predictable style of returning errors is more important.

You'd get normal errno/out param semantics if you had access to semantic struct unpacking. But you don't. Even then, composing optional values in C has always been a bit of a pain. If you're not doing exceptions, your two choices seem to be exceptions and monads in every language, and neither work in C, or would even be compatible with the philosophy that most C programmers have. I guess you could attempt to pull some kind of macro but it only works on simple one-to-the-other calls. C++ optionals, as terrible as C++ is, are certainly more fun to use than

    if(foo(x,y, out1, out2) != WHATEVER_LIBRARY_OK) { ... }

Re: My personal C coding style as of late 2023

#448
post #57

Earlier quoted context omitted.

(self-reply) One more thing. > I could use _Bool, but I’d rather stick to a natural word size and stay away from its weird semantics. This is even more subjective, but personally I like _Bool's semantics. They mean that if an expression works in an `if` statement: if (flags & FLAG_ALLOCATED) then you can extract that same expression into a boolean variable: _Bool need_free = flags & FLAG_ALLOCATED; The issue is that…

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…

For:

  if (need_free == some_other_bool)
you could use:

  if (!need_free ^ some_other_bool)
if you're using _Bool.

Re: My personal C coding style as of late 2023

#449
post #407

Earlier quoted context omitted.

Yes it does bend rules. Say that a , b and c are small integers (we don't worry about addition overflow). Given an inequality formula like: a we can safely perform this derivation (add -b to both sides): a - b This is not true if a , b and c are unsigned. Or even if just one of them is, depending on which one. What I mean by "bend the rules of arithmetic" is that if we decrement from zero, we suddenly get a large val…

> What I mean by "bend the rules of arithmetic" is that if we decrement from zero, we suddenly get a large value. Yes completely consistent with rules of modular arithmetic. A programmer ought to be able to extend math horizons beyond preschool. Which is ironic because I can explain this concept to my 6 year old on a clock face and it’s easy for them to grasp. > Unsigned tricks with circular buffer indices will not d…

> Yes completely consistent with rules of modular arithmetic.

In modular arithmetic, there is no such thing as <. (To put it precisely, ℤ_𝑛 is not an ordered ring.) Or are you teaching your 6-year old that 9:00 today is later than 7:00 tomorrow?

Post reply on HN