[comp.std.c] static int x[2], *p = x+

eggert@ata.twinsun.com (Paul Eggert) (09/14/90)

ANSI C 3.4 (page 56 lines 22-27) says:

	More latitude is permitted for constant expressions in initializers.
	Such a constant expression shall evaluate to one of the following:

	o	an arithmetic constant expression,
	o	a null pointer constant,
	o	an address constant, or
	o	an address constant for an object type plus or minus an
		integral constant expression.

What does ``evaluate to'' mean here?  I thought evaluation yields a value
(see 3.1.5), but here it seems to yield an expression.  For example, which
of the following declarations are OK, and why?

    static int x[2];
    static int *p = 1 + x; /* int+addr, not addr+int */+
    static int *q = x + (int)(0.1 + 0.9); /* Does this ``evaluate to'' x+1? */
    static int *r = &x[(int)(0.1 + 0.9)]; /* Is this equivalent to the above? */
    static int *s = x + (x-x); /* Does this ``evaluate to'' x+0? */


A nit: the phrase ``pointer to an lvalue ... or to a function designator''
(lines 32-33) is sloppy, because lvalues and function designators are
_expressions_, while pointers point to _objects_.

drh@cs.Princeton.EDU (Dave Hanson) (09/14/90)

In article <1990Sep14.015241.2152@twinsun.com> eggert@ata.twinsun.com (Paul Eggert) writes:
    ANSI C 3.4 (page 56 lines 22-27) says:
    	More latitude is permitted for constant expressions in initializers.
    	Such a constant expression shall evaluate to one of the following:
    	o	an arithmetic constant expression,
    	o	a null pointer constant,
    	o	an address constant, or
    	o	an address constant for an object type plus or minus an
    		integral constant expression.
    What does ``evaluate to'' mean here?  I thought evaluation yields a value
    (see 3.1.5), but here it seems to yield an expression.

`evaluate to' means to evaluate to a value that can be
computed at compile time, which includes link time.

    For example, which
    of the following declarations are OK, and why?
    
        static int x[2];
        static int *p = 1 + x; /* int+addr, not addr+int */+
        static int *q = x + (int)(0.1 + 0.9); /* Does this ``evaluate to'' x+1? */
        static int *r = &x[(int)(0.1 + 0.9)]; /* Is this equivalent to the above? */
        static int *s = x + (x-x); /* Does this ``evaluate to'' x+0? */

first initialization is legal; 1+x *is* `int+addr'
because x is an address constant.

the 2nd and 3rd are equivalent and are debatable because
floats that appear integral constant expressions must appear
only as the immediate operands of casts (sec. 3.4).
i'd guess that most compilers will accept these, however,
because it's difficult to do otherwise.

even though (x-x) is 0, compilers may not be obliged
to recognize it as 0 because x-x doesn't conform to the allowable
expressions you listed above.

volpe@underdog.crd.ge.com (Christopher R Volpe) (09/15/90)

In article <2699@rossignol.Princeton.EDU>, drh@cs.Princeton.EDU (Dave
Hanson) writes:
|>        static int *s = x + (x-x); /* Does this ``evaluate to'' x+0? */
|>
|>even though (x-x) is 0, compilers may not be obliged
|>to recognize it as 0 because x-x doesn't conform to the allowable
|>expressions you listed above.

Yes, they are obliged to recognize it as zero because the two 
operands (which happen to be identical) are both pointers into
the same array. See K&R II A7.7
                                    
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

drh@cs.Princeton.EDU (Dave Hanson) (09/16/90)

In article <11907@crdgw1.crd.ge.com> volpe@underdog.crd.ge.com (Christopher R Volpe) writes:
    In article <2699@rossignol.Princeton.EDU    , drh@cs.Princeton.EDU (Dave
    Hanson) writes:
    	    static int *s = x + (x-x); /* Does this ``evaluate to'' x+0? */
    	    
    	    even though (x-x) is 0, compilers may not be obliged
    	    to recognize it as 0 because x-x doesn't conform to the allowable
    	    expressions you listed above.
    
    Yes, they are obliged to recognize it as zero because the two 
    operands (which happen to be identical) are both pointers into
    the same array. See K&R II A7.7

x-x indeed evaluates to 0 during execution, but compilers are not
obliged to recognize it as a constant expression that evaluates to 0
during compilation. x-x is not an integral constant expression because
its operands are address constants, not integer constants (see sec. 3.4).

volpe@underdog.crd.ge.com (Christopher R Volpe) (09/17/90)

In article <2752@rossignol.Princeton.EDU>, drh@cs.Princeton.EDU (Dave
Hanson) writes: [in regard to:  static int *s = x + (x-x); ]
|>x-x indeed evaluates to 0 during execution, but compilers are not
|>obliged to recognize it as a constant expression that evaluates to 0
|>during compilation. x-x is not an integral constant expression because
|>its operands are address constants, not integer constants (see sec. 3.4).

Yup. Right. Sorry.
               
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com