[augeas-devel] Re: Review of the Augeas API
Jim Meyering
jim at meyering.net
Mon Apr 21 19:35:56 UTC 2008
David Lutterkort <dlutter at redhat.com> wrote:
...
>> -static struct path *make_path(struct tree *root, const char *path) {
>> +static struct path *make_path(const struct tree *root, const char *path) {
>> struct path *result;
>>
>> CALLOC(result, 1);
>> if (result == NULL)
>> return NULL;
>> - result->root = root;
>> + result->root = (struct tree *) root;
>
> I started declaring various fields in internal structs as const
> pointers, but invariably I wind up doing casts like the above, which
Bear in mind that I hate "casts" with a passion, and have gone to great
lengths to avoid them in coreutils, and gnulib, among other projects.
I would not suggest the one above if there were a better way.
Remember: the interface is what matters. If you force non-const into
an interface that is really const, you force const-correct *callers*
to cast away const when they call your interface. Otherwise they'd get
warnings. So the priority is to make all interfaces const that
can be. It's ok to add a cast internally, if necessary.
I can tell you from experience with glib that having to
add casts to my code to accommodate a const-incorrect API
is quite annoying.
E.g., some str* functions take const char* pointers yet return a
"char *" that's aliased to the const parameter. The only
way to get from one to the other is via a cast.
> just doesn't feel right.
Good reflex, but the cost of the alternative is too high.
> A common case is where a struct contains a
> string that is almost always read-only, but when you free the struct you
> need to write something ugly like 'free((char*) state->string)'
As far as const correctness goes, struct member types are different
from pointer parameters. If a member is a pointer that gets a value
returned from the likes of malloc, then something has to write through
the pointer. Hence, the member pointer type must not be "const".
More information about the augeas-devel
mailing list