Subject: Re: __UNCONST(a)
To: Roland C. Dowdeswell <elric@imrryr.org>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 07/03/2004 14:43:43
[ On Friday, July 2, 2004 at 15:03:20 (-0400), Roland C. Dowdeswell wrote: ]
> Subject: Re: __UNCONST(a) 
>
> How exactly do you return an element of an array while promising
> that you are not going to modify it then?

Well the glib answer is that you're misusing "const" then.  ;-)

Let's remember that the _sole_ (original) purpose of "const" is to
designate objects whose value is unchanging.  The compiler emits
warnings in an attempt to ensure that the programmer does not ever
change the designated object (e.g. so that the linker/loader could
assign it to a read-only area of memory).

Thus using "const" to designate function parameters which will not be
changed is indeed strictly speaking a mis-use of "const" -- however it's
also the kind of thing that the C standards committee(s) have themselves
done and would seem to encourage.

I.e. the standards-specified functions which effectively de-const the
pointers passed to them are great gaping pointer aliasing holes that
embedded programmmers can easily be sucked through without warning.

I don't know what the practical answer to this apparent dichotomy is
though....  It would indeed be very nice to have a safer way to declare
that a function will not modify the object(s) passed to it by reference,
but "const" is not a safe way to do that in Standard C, at least not
when the function also returns a pointer (in)to the same object.  Peter
Van Der Linden quotes Ken Thompson in his book "Expert C Programming:
Deep C Secrets" giving this apropos observation:

	The 'const' keyword only confuses library interfaces with the
	hope of catching some rare errors.

Perhaps the safest and least confusing way to use "const" for function
parameter declarations is to use an explicit cast to shut off the
"incompatible pointer type" warnings when pointers are returned by
reference.  This way everything is in one place, i.e. the pointer
aliasing and "const" discarding is not hidden away in some system
library implementation.  E.g., if I've got my delcarations right,
something like this:

void foo(const char *, char const **);

void
foo(const char *bar, char const **none)
{
        *none = bar;
}

 . . . 

        char blah[100];
        char *bork;

 . . . 

        foo(blah,  (char const **) &bork);
        *bork = '\0';

Note that there's no "cast creates fake const qualifier" warning.  :-)
(since it's always considered safe to add "const" to something -- just
not to take it away again, especially not in some other context)

That doesn't help any of the existing Standard C API though....

I've been planning since before this thread restarted to raise this
topic at a monthly dinner meeting of local comp-sci geeks which I
usually attend -- one of our group is a former member of the ANSI C
committee, another works daily on GCC, and two of the others each have
as much or more experience at porting software as my own considerable
two decades worth.

-- 
						Greg A. Woods

+1 416 218-0098                  VE3TCP            RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com>          Secrets of the Weird <woods@weird.com>