[comp.lang.c] Taking addresses of constants

entropy@pawl.rpi.edu (Math Student from Hell) (06/18/89)

Consider the following code:

static char foo[]="\0\0\0\0\0\0\0\0";
...
{
auto char **x; /* 'foo' has type (char *), 
                   so '&foo' will have type (char **) */
x = &foo;

**x = 'w';
}

Now, this code should be illegal and fail to compile, because 'foo' is
a constant expression and so has no address.  or, if the compiler
allows this, it ought to stick the value of 'foo' in some static area
and then generate code that assigns the address of this area to 'x' at
the appropriate time.

The old IBM 370 C compiler (Meaning the one that came out before last
month) does neither of these things.  It generates assembly
code that carries out the statement

	x = foo;

instead of 

	x = &foo;

And thus, when I execute **x = 'w';,  I get a segmentation violation.

Now:

1) Is this a common mistake?  Is it a mistake at all?

2) What does the ANSI standard have to say about this kind of situation?
   Is '&foo' disallowed entirely, or does the compiler have to stuff
   the value of 'foo' somewhere and then give you a pointer to it?

Thank you.


    What a wonderful thing is the human brain; how I wish I possessed one.
Mark-Jason Dominus 	   entropy@pawl.rpi.EDU	     entropy@rpitsmts (BITnet)

chris@mimsy.UUCP (Chris Torek) (06/19/89)

In article <5537@rpi.edu> entropy@pawl.rpi.edu (Math Student from Hell) writes:
>Consider the following code:
>
>static char foo[]="\0\0\0\0\0\0\0\0";
>...
>{
>auto char **x; /* 'foo' has type (char *), 
>                   so '&foo' will have type (char **) */

`foo' does not have type (char *).  Its type is (char [9]), or
`array 9 of char' in pseudo-English.  &foo is therefore illegal
in Classic C (K&R-1), and has type (char (*)[9]), `pointer to
array 9 of char', in New C (pANS, K&R-2).

>x = &foo;

This is illegal in both kinds of C: in Classic C, because &foo is
illegal, and in New C, because the types of x and &foo do not match.

>**x = 'w';
>}

What this does, if you add casts to sleaze it by the compiler, is
unpredictable.

>Now, this code should be illegal and fail to compile,

Right, but ...

>because 'foo' is a constant expression and so has no address.

wrong reason.  `foo' is an array and has an address; each element
of that array also has an address.

>or, if the compiler allows this, it ought to stick the value of 'foo'
>in some static area and then generate code that assigns the address
>of this area to 'x' at the appropriate time.

This is a reasonable interprtation, but not the one taken in the pANS.
Some compilers (VMS C) have an extension that allows `&' to be applied
to rvalues; the meaning of

	&(expression)

(where expression is not an rvalue) is essentially

	{ static appropriate_type unnamed_var;
	  unnamed_var = (expression);
	  return &unnamed_var; }

so that, for instance,

	int *p = &3;

generates code equivalent to

	int _fake = 3;
	int *p = &fake;

This extension is just that: an extension.  VMS C might only allow this
in function calls (though that would be stupid).

>The old IBM 370 C compiler ... does [something else].

If it does not at least give a warning, this is a bad implementation.

>And thus, when I execute **x = 'w';,  I get a segmentation violation.

That much is entirely appropriate.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris