From: darcy@druid.uucp (D'Arcy J.M. Cain)
Subject: Re: HIgher problems at hand. HELP!
Date: Mon, 27 Jul 1992 20:34:35 GMT
Organization: D'Arcy Cain Consulting

fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
>darcy@druid.uucp (D'Arcy J.M. Cain) writes:
>> * modified for ANSI by D'Arcy J.M. Cain
>>/* The following define required for full checking.  The problem is that */
>>/* the function has to ultimately assign a const char * to the return */
>>/* value which has to be char *.  The answer is to drop the use of */
>>/* const in this module and trust the code to do the right thing */
>>#define		const
>Yuck!
>Do *not* #define keywords unless you have absolutely no alternative.

I didn't think that I did.  Note that I am not suggesting this kind of
thing in ordinary programs.  Since strstr is a standard function this
can be viewed as part of the implementation and of course you should
take care that this works in your environment.  I think, however, that
this method is the best solution and will work with most if not all
current compilers.

>>#include	<string.h>
>Now what happens if string.h happens to contain
>	const CHAR_BIT = 8;
>or some such?

Then you get rid of your compiler and get a standard one.  Exactly what
do you think the above construct is doing?

>>char	*strstr(const char *s, const char *wanted)
>This is a *different* prototype to the externally visible one, since
>this one doesn't include "const". An implementation is well within it's
>rights to give you a warning at link time, and probably even an error.

Well the prototype isn't visible to the linker however I think I see what
you are getting at.  Perhaps it is theoretically possible that the calling
sequence will be different for commands that take const pointers than ones
that take non-const pointers but I would be really surprised.  Remember
that functions that take consts must also accept non-consts as well.  The
function has no way of knowing what kind it is, only if it is allowed to
modify it **through the given pointer**.

>The solution to the const problem is just to put a cast in the final return
>statement:
>	return (const char *) s;

I suppose you mean "return (char *) s" since what you are returning is
actually a const but the function needs to return a non-const.  Here is
the real problem that I am attempting to overcome.  This, to my mind, is
one of the two major flaws (*) in C.  There is no way to describe this
type of function, one that may take one of a number of types and returns
the type of the actual argument.  other examples of this type of function
include memchr, memcmp, strchr, strpbrk and strrchr.  They all have to
return a pointer to char but all they have is a pointer to const.  If
you use Gnu and turn on all the warnings it will, properly IMO, warn
you that you are doing something suspicious no matter how you code
these functions because you *are* doing something suspicious.  In
fact the standard prototypes for these functions actually lie since
they claim that the functions return a non-const when in fact they don't
always do so.  What C needs is a new qualifier which says in effect
that a function returns the type qualified the same as its first
argument.  I call it type "magic" and would work something like this.

    magic char *strstr(const char *, const char *);

and means that strstr takes a const but the return is so qualified only
if the actual argument in a particular case is.  It's clumsy and I don't
really suggest that it be considered for the standard but it illustrates
the problem.  As it stands if you have something like:

    char *p;
    const char *cp;
    ...
    p = strstr(cp, "SOME STRING");

you can modify the string pointed to by cp and there is no way that the
compiler can catch it.

Of course the other option is to just ignore the warnings but I don't
like to do that.


(*) The other flaw IMO is that there is no way to describe a function
that doesn't return.  Gnu allows functions to be qualified as volatile
to implement this but of course that isn't portable.  Perhaps it will
be considered existing practice by the time the standard is next up
for review.

-- 
D'Arcy J.M. Cain (darcy@druid.com)  |
D'Arcy Cain Consulting              |   There's no government
Toronto, Ontario, Canada            |   like no government!
+1 416 424 2871          DoD#0082   |