Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros or custom abstractions.
Heh, good luck avoiding the use of macros in sufficiently complex projects - sometimes C just can't use some control structures in an elegant manner without using macros or custom abstractions.
Sir, yes, sir. I will throw away "offsetof" and "container_of" right now, just give me a moment.
> Do not use a typedef to hide a pointer or avoid writing “struct”
Somewhat agree with the former, but completely disagree with the latter. If there's a single thing that is not right with C is its excessive verbosity in places where none is needed.
Not typedef'ing your structs forces you to use extra 7 characters per type mention for no clear benefit. To put it differently - if NOT having "struct" in front of a type name has any effect on readability/maintainability of your code, then there are deeper problems with your coding style that won't be solved by dragging "struct" around.
The benefit is to readability. You should treat structs differently from scalars, and the code should make the distinction apparent. You should not generally, for example, pass structs by value. This is just laziness.
> scalars
So you would typedef the scalars then? If you don't, then scalars will be the built-in types (which you'd presumably know well) and then all other type names will be typedef'ed structs/unions, still making it trivial to recognize them as such.
`struct foo` is a bit more instructive when understanding code than `foo`; at worst, they read the same to someone familiar to the codebase, at best they prevent the need to flip back and forth to the type definitions.
foo_s
bar_u
baz_e
for structs, unions and enums respectively. Perhaps even splurge on xyz_f for function pointers... though that's getting recklessly close to the Hungarian notation :)I definitely never panicked as a kid when I saw WINAPI-related code.
Of course, it is copied because "by value". On the AMD64 architecture your compiler will transfer your little structs in registers.
For me this is cargo cult maintainability: it has the sound of a good advice, but doesn't seem grounded in reality.
However I generally agree, that macros are pretty much unavoidable. Include guards are implemented using macro constants. It is pretty much the only portable way to force inlining (in some cases this might be necessary). Variadic macros are a easier to create that variadic functions (e.g. wrapper around fprintf for logging). And there is also the '_Generic' thing for people, who can use C11.
As for include guards one has to look really hard [1] to get a compiler that does not support #pragma once.