[comp.lang.c] Question on const applied to typedef'd pointer

ado@elsie.UUCP (Arthur David Olson) (02/25/89)

Here's a typescript obtained using the GNU C compiler (version 1.34):

	Script started on Fri Feb 24 20:43:19 1989
	elsie$ cat try.c
1>	const char * const	foo;

	typedef char *		bar;

2>	const bar const		baz;
	elsie$ gcc -c try.c
	try.c:5: warning: duplicate `const'
	elsie$ exit

	script done on Fri Feb 24 20:43:38 1989

The question for the gurus:  should line 1 above have the same meaning as
line 2 above, despite gcc's warning?
-- 
	Arthur David Olson    ado@ncifcrf.gov    ADO is a trademark of Ampex.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/25/89)

In article <9078@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes:
>1>	const char * const	foo;
>	typedef char *		bar;
>2>	const bar const		baz;
>The question for the gurus:  should line 1 above have the same meaning as
>line 2 above, despite gcc's warning?

No; you can't slip a qualifier "inside" an existing typedef.
GCC is correct; both "consts" apply at the same lexical level,
namely to the "bar" type.  The line tagged "2>" above is the
same as
	char * const const	foo;

ado@elsie.UUCP (Arthur David Olson) (02/28/89)

> > 1>	const char * const	foo;
> >	typedef char *		bar;
> > 2>	const bar const		baz;
> > . . .should line 1 above have the same meaning as line 2 above. . .

> No; you can't slip a qualifier "inside" an existing typedef.

Thanks for the reply; now it's time for Double Jeopardy:

Suppose you're working with software such as MIT's X Window System,
which has declarations such as
	typedef char *String;
and
	typedef Widget *WidgetList;
in its header files.  Suppose also you have a function argument of type
String that refers to an object you're not supposed to change, and that
you want to ensure isn't itself changed in the body of the function.
Now if the argument was a plain "char *", you could use
	void function(const char * const argument) { /* whatever */ }
to achieve the desired effect.  But what of "String"?   Using
	void function(const String const argument) { /* whatever */ }
won't work, as explained in the reply.  Is there some other way to do the job?
-- 
	Arthur David Olson    ado@ncifcrf.gov    ADO is a trademark of Ampex.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (02/28/89)

In article <9081@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes:
>Now if the argument was a plain "char *", you could use
>	void function(const char * const argument) { /* whatever */ }
>to achieve the desired effect.  But what of "String"?   Using
>	void function(const String const argument) { /* whatever */ }
>won't work, as explained in the reply.  Is there some other way to do the job?

Sure; use the first form (involving char *).  Despite appearances,
typedef does not create a new type.  Of course, you could define a
CString typedef that is just like a String except that the bytes
pointed at are considered read-only, then use the CString typedef
as shorthand in your example.

I appreciate why you'd like to do things the way you suggest, but
if you think hard enough about it you'll realize that it cannot be
made to work in full generality -- there can be many levels within
a type at which "const" could be applied, but the typedef name has
only two adjacent sides as possible slots for sticking in "const",
not enough for all the possible levels.

karl@haddock.ima.isc.com (Karl Heuer) (03/02/89)

In article <2105@solo11.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:
>>In article <9078@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes:
>>>	typedef char *		bar;
>>>	const bar const		baz;
>>No; you can't slip a qualifier "inside" an existing typedef.
>>[That attempt] is the same as
>>	char * const const	foo;
>
>Why? I find this illogical.

Let me restate with a different example.  After `typedef char *string',
`string const x' means `char * const x' rather than `char const * x'.  Do you
still find this illogical?  In my opinion, this is true for essentially the
same reason that `string x, y' means `char *x, *y' rather than `char *x, y'.
Once you've created the typedef, it's set in stone.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint