Live data from Hacker News

My personal C coding style as of late 2023

nullprogram.com

61–70 of 466 posts

Re: My personal C coding style as of late 2023

#61
post #43

> #define sizeof(x) (size)sizeof(x) Undefined behavior[1] > #define assert(c) while (!(c)) __builtin_unreachable() Undefined behavior[1] > I’ll cast away the const if needed. Undefined behavior[2] > The assignments are separated by sequence points, giving them an explicit order. I don't believe assignments are sequence points and only the function call is. [1] https://en.cppreference.com/w/c/language/identifier#Reser…

> Undefined behavior[2]

Given that this particular undefined behavior usually causes crashes in practice, I expect the author is talking about casting away the const but not actually writing to the pointer. Which is legal.

Re: My personal C coding style as of late 2023

#62
post #51

While there are a few disagreeable points, I like the article. I've always felt that C is unfairly maligned. Yes, it's very low level, it's meant to be. Yes, it lets you shoot yourself in the foot, but what language doesn't? Most of the problems with C are really issues with the standard library, the Unix (now Posix) interfaces, and the string type. None of these are actually part of C, but are part of how C is norma…

It's not unfairly maligned, it's just that everyone remembers their college/university 'learning experience' which made no distinction between C/C++, they were told to use the Borland compiler, and when trying to learn printing "hello world" they only got a `segmentation fault` error instead of a stack trace. When they asked why it's so hard, they were told C/C++ is hard - so they dropped the class.

Then they picked up a JS or Python class, were told high-level languages are easy and viola! they started to understand programming.

That's the reason people are spiteful of it. They had a terrible learning experience right out the gate.

Re: My personal C coding style as of late 2023

#63
post #21

Earlier quoted context omitted.

It depends entirely on the architectures | CPUs, that said the obvious case from past experience is numeric processsing jobs where (say) you flow data into "per cycle" structs that lead with some conditionals and fill out with (say) 512 | 1024 | 2048 sample points for that cycle (32 or 64 bit ints or floats) .. the 'meat' of the per cycle job. My specific bug bear here was a junior who insisted "saving space" by pack…

This is the use case for `uint_fast8_t` (part of the C99 standard); it should use whatever width of unsigned integer is enough to store a byte, but fastest for the platform. You always know that the type can be serialized as 8 bits, but it might be larger in memory. So long as you don't assume too much about your struct sizes across platforms, it should be a good choice for this. Although, if alignment is an issue, i…

10 years ago when ATmegas were still around and your 32 bit variable was generating 3 instructions for addition I would say „right on“ but now everything is a 32 bit Cortex-M and please stop polluting your code with this nonsense

Re: My personal C coding style as of late 2023

#64
post #55
post #22

Earlier quoted context omitted.

> This seems like a bad idea, because the whole point of an assert is that something shouldn't happen, but might due to a (future?) bug. And so it’s a bad idea because…? The whole idea is to notice a bug before it ships. Asserts are usually enabled in test and debug builds. So having an assert hit the “unreachable” path should be a good way to notice “hey, you’ve achieved the unexpected” in a bad way. You’re going to…

It's undefined behavior if the assert triggers in production. It's too greedy for minor performance benefit at the risk of causing strange issues.

Yikes. I did have to go down a little rabbit hole to understand the semantics of that builtin (I don’t normally write C if that wasn’t immediately obvious from the question) but that seems like a really questionable interpretation of “this should never happen”. I would expect the equivalent of a fault being triggered and termination of the program, but I guess this is what the legacy of intentionally obtuse undefined behavior handling in compilers gets you.

Re: My personal C coding style as of late 2023

#66
post #39

I like it a lot. Especially the part about ditching const qualifiers. They clutter function declarations, don't make the intent any clear, and almost never improve performance. Restrict, on the other hand, I've found makes the compilers emit better code in many cases. But I don't like using 1 and 0 instead of booleans. Many standard C functions (fclose for example), return 0 on success. Better to be explicit here.

I use an exitint typedef to signify "0 is success, non-0 is failure" and boolint equivalent to his b32. Not typesafe of course, so it's just info for fallible humans.

Re: My personal C coding style as of late 2023

#67
post #61
post #43

> #define sizeof(x) (size)sizeof(x) Undefined behavior[1] > #define assert(c) while (!(c)) __builtin_unreachable() Undefined behavior[1] > I’ll cast away the const if needed. Undefined behavior[2] > The assignments are separated by sequence points, giving them an explicit order. I don't believe assignments are sequence points and only the function call is. [1] https://en.cppreference.com/w/c/language/identifier#Reser…

> Undefined behavior[2] Given that this particular undefined behavior usually causes crashes in practice, I expect the author is talking about casting away the const but not actually writing to the pointer. Which is legal.

The legal cases in which he needs to cast away const could be avoided if the arguments to called functions were appropriately qualified.

Re: My personal C coding style as of late 2023

#68
post #40

> #define sizeof(x) (size)sizeof(x) Technically, it's illegal to #define over a language keyword.

Also, `#define countof(a) (sizeof(a) / sizeof(*(a)))` is unsafe since the arg is evaluated twice.

Arguments to sizeof aren’t actually evaluated (except for variably-modified-types, AKA VLAs, but don’t use those).

Re: My personal C coding style as of late 2023

#69
post #64
post #55

Earlier quoted context omitted.

It's undefined behavior if the assert triggers in production. It's too greedy for minor performance benefit at the risk of causing strange issues.

Yikes. I did have to go down a little rabbit hole to understand the semantics of that builtin (I don’t normally write C if that wasn’t immediately obvious from the question) but that seems like a really questionable interpretation of “this should never happen”. I would expect the equivalent of a fault being triggered and termination of the program, but I guess this is what the legacy of intentionally obtuse undefined…

The builtin itself is fine. It works exactly as it's intended. It says "I've double and tripple checked this. Trust me compiler. Just go fast". But you should not use it to construct an assert.

Re: My personal C coding style as of late 2023

#70
post #40

> #define sizeof(x) (size)sizeof(x) Technically, it's illegal to #define over a language keyword.

Also, `#define countof(a) (sizeof(a) / sizeof(*(a)))` is unsafe since the arg is evaluated twice.

The arg is expanded twice but evaluated zero times, since sizeof gives the size of its argument type without executing anything.
Post reply on HN