2 ms·
I tend to agree with this approach and use it myself (in the rare instances that I use C). My only complaint is that as the number of functions touching the str
by Arnor 13y ago
I tend to agree with this approach and use it myself (in the rare instances that I use C). My only complaint is that as the number of functions touching the struct grow, maintainability gets harder. Can you share any rules/strategies to mitigate this problem?
- acqq 13y agoLike always "divide and conquer." In a big program, I identify "subprograms" that can have only the "interface" (the very limited set of structures and functions) exposed to the rest. The subprograms aren't "libraries" in a sense that I do much faster changes to the "interface" but just having them makes everything much more maintainable. So some headers are visible only inside of the "subprogram." Second: not everything is worth to appear in headers at all: I use the functions and declarations local to the compilation unit as much as I can. Back to the main topic, using structures properly will result in the best code you can produce for anything not trivially small. Practically every CPU I know of is specifically optimized to make addressing elements in the C structure as efficient as possible. In your case, if there are a lot of functions to which you pass the pointer to the structure, then if you take care of the organization it means that they really do have to operate on the structure. But if you have a lot of arguments to any function, you probably need some even bigger structure and pass that around.
- yoklov 13y agoYou basically split it up in a similar way that you'd use in an OO language, except you don't have inheritance and only have composition. Specifically, you break apart the logically distinct portions of your structs and you make them structs themselves. E.g. compare (trivial examples, but you get the idea). /* okay */ struct monster { unsigned id; int x, y, hp; /* etc. */ }; /* better */ struct point { int x, y; }; struct monster { unsigned id; struct point pos; int hp; }; This also allows a form of inheritance. For example if you have struct bad_monster { struct monster base; int badness; /* your imagination is the limit. */ }; /* this is safe */ struct bad_monster bad; struct monster *some_monster = (struct monster *)&bad; /* equivalently &bad.base */ some_function_expecting_a_monster(some_monster); /* only safe if it was originally a struct bad_monster */ struct bad_monster *bad_ptr = (struct bad_monster *)some_monster; Those are the ways I tend to break up structs when writing C code. Basically by using lots of composition.
- acqq 13y agoAnd the good aspect of C is the "flatness" of the structures: they are not "objects" with the hidden content and associated functions managing it. It's a way for the programmer to organize the data as efficiently as possible.