const and talloc_reparent

tridge at samba.org tridge at samba.org
Sat Jul 4 00:37:15 GMT 2009


Hi Tim,

 > 726: In talloc_reparent you can't take in a const void *, and then  
 > return it as a void *.

yes, you can, and in this case it is the correct thing to do.

The C language doesn't allow this type of function to be done as a
single function with const correctness. To explain why, let's look at
the strchr() function from libc:

       char *strchr(const char *s, int c);

notice it takes a const and returns the same string as non-const? This
was done as the only other way to do it in C without const warnings is
to have two functions:

       char *strchr_nonconst(char *s, int c);
       const char *strchr_const(const char *s, int c);

then ask programmers to call the right one. That is considered to be
too ugly, and puts too great a burden on programmers (not to mention
documentation), and requires duplication of code in the library.

So, instead, library interfaces commonly use the "takes const and
returns non-const" approach as it means that the const nastiness is
hidden away in the library. That is what talloc_reparent() does.

You are right that I should have squashed the warning by using
discard_const(), and I'll put in a patch for that and the other
similar warning now.

Basically const in C is broken. We just need to live with it as best
we can, but please don't take const chasing too seriously, as it is
not a game that can be won without changing to a new language. 

I should also mention that we could have used a quite different
interface for talloc_reparent(), like this:

  bool talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr);

and in that case we would have avoided the const problems in C, but at
the expense of a worse interface, as you could no longer do what is
commonly done:

  a->ptr = talloc_reparent(old_ctx, new_ctx, ptr);

which is the style we have chosen for talloc.

Cheers, Tridge


More information about the samba-technical mailing list