[comp.lang.c] Are addresses of const members const?

sdm@cs.brown.edu (Scott Meyers) (02/07/91)

For both ANSI C and as-ANSI-as-we-have C++, are the members of a const
struct themselves const?  Consider this:

    struct Foo {
      char *data;
    };

    char * f(const struct Foo x)
    {
      return x.data;
    }

Within function f, x is a const.  Is x.data therefore a const?  If so,
there should be a type mismatch between the expression being returned
(const char *) and the function's return type (char *).  Yet this example
sails through 3 C++ compilers (g++, cfront 2.0, Sun cfront 2.1 beta) and
one ANSI C compiler (gcc) without so much as a wimper.

The same question can be put this way:  is the following legal?

    const struct foo x;
    char **p = &(x.data);  /*  lhs = char **, rhs = const char **  */

If the members of a const structure are themselves supposed to be const,
I'd appreciate it if you'd point me to an authoritative reference that says
so.  For C++, I looked in the ARM, but couldn't find anyplace where it said
what should happen.  For C, all I've got is the second (ANSI C-based)
edition of K&R, but I couldn't find any information in there, either.

Thanks,

Scott

-------------------------------------------------------------------------------
What do you say to a convicted felon in Providence?  "Hello, Mr. Mayor."

ark@alice.att.com (Andrew Koenig) (02/08/91)

In article <63928@brunix.UUCP> sdm@cs.brown.edu (Scott Meyers) writes:

>     struct Foo {
>       char *data;
>     };

>     char * f(const struct Foo x)
>     {
>       return x.data;
>     }

> Within function f, x is a const.  Is x.data therefore a const?

Yes, in both ANSI C and C++, but that doesn't have the implications
you think it does.  For example, the ANSI C standard gives
the following example in section 3.5.3 (slightly abbreviated here):

	const struct s { int mem; } cs = { 1 };
	int * pi;

	pi = &cs.mem;	/* violates type constraints for = */


> Yet this example
> sails through 3 C++ compilers (g++, cfront 2.0, Sun cfront 2.1 beta) and
> one ANSI C compiler (gcc) without so much as a wimper.

When you say that x is a const Foo, that means that x.data is itself
a constant -- but that doesn't say anything about the memory to which
x.data points.  In other words, the type of x.data is char *const,
which is distinct from const char *.  In particular, there is no problem
assigning a char *const to a char *.
-- 
				--Andrew Koenig
				  ark@europa.att.com

guy@hpgnd.grenoble.hp.com (Guy DUBRISAY) (02/08/91)

'const' is a type modifier whose effect is to tell the compiler that an object
such declared cannot be written to (asigned to, incremented, decremented, ...).
Statements which are detected by the compiler to do so will cause an error.

Obviously any variable may be modified by 'const' argument whatever their type
is.

Beware of using 'const' modifier altogether with pointers :

const char * ptr ;	==> The pointer may be modified, but that which it
			    points to may not.

char * const ptr ;	==> The pointer may not be modified, but that which
			    it points to may.

const char * const ptr;	==> Neither the pointer nor that which it points to
			    may be modified.

Reading your code :

>const foo *aray1[] = { &item1, &item2 };
>const bar aray2[] = { &item1, &item2 }; 

... should NOT gives 'type mismatch' error!

> aray1[0] = &item3;

... is legal (modified pointer). This should cause an error if you had 
declared
		const foo * const aray1[] = { &item1, &item2 };

> aray2[0] = &item3;

... must produce an error such as "Cannot assign to a constant."

Hope this helps.

Guy.