[comp.lang.c] `interesting' program

maart@cs.vu.nl (Maarten Litmaath) (07/07/89)

----------8<----------8<----------8<----------8<----------8<----------
/* Any comments? */

struct	foo {
		int	mids;
	};


struct	foo	zork()
{
	struct	foo	foo;


	foo.mids = 79;
	return foo;
}


/*
 * Try:
 *	cc -DFOO foo.c
 *	cc -DBAR foo.c
 *	cc foo.c
 *	gcc -DFOO foo.c
 *	gcc -DBAR foo.c
 *	gcc foo.c
 *
 * and compare!
 */

main()
{
#if	!FOO && !BAR
	struct	foo	bar;


	bar = zork();
#endif
	printf("%d\n",
#if	FOO
		zork().mids
#else
#if	BAR
		(&zork())->mids
#else
		bar.mids
#endif
#endif
	);
}
----------8<----------8<----------8<----------8<----------8<----------
Results:
1)	Sun 3/50 w/ SunOS 3.5 cc dislikes FOO, likes BAR
2)	Sun 3/50 w/ SunOS 3.5 gcc 1.32 likes FOO, dislikes BAR
3)	Sun 4/280 w/ SunOS Sys4-3.2 cc likes FOO, likes BAR

IMHO 2) is the winner! ISEHO 3) is right.

I say: zork() is a constant of type struct foo, so you cannot take its
address and it isn't an lvalue.
SE says: zork() is the name of a struct foo, so you CAN take its address.
-- 
"I HATE arbitrary limits, especially when |Maarten Litmaath @ VU Amsterdam:
   they're small."  (Stephen Savitzky)    |maart@cs.vu.nl, mcvax!botter!maart

frank@zen.co.uk (Frank Wales) (07/11/89)

In article <2833@solo8.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
[program deleted]
>I say: zork() is a constant of type struct foo, so you cannot take its
>address and it isn't an lvalue.
>SE says: zork() is the name of a struct foo, so you CAN take its address.

IMHO, zork() is a constant too, and hence not an lvalue.  Both the
HP-PA cc (3.01) and its xdb agree, and although I would be the last
person to advocate using a compiler to confirm the language definition,
I trust this one more than most.  Maybe SE is used to C on some lazy
or old-fashioned machine (e.g., a Sun386i running 4.0.1 SunOS, which
allows both this().that and (&these())->those, producing equivalent code).
--
Frank Wales, Systems Manager,        [frank@zen.co.uk<->mcvax!zen.co.uk!frank]
Zengrange Ltd., Greenfield Rd., Leeds, ENGLAND, LS9 8DB. (+44) 532 489048 x217 

shankar@hpclscu.HP.COM (Shankar Unni) (07/11/89)

> IMHO 2) is the winner! ISEHO 3) is right.
> 
> I say: zork() is a constant of type struct foo, so you cannot take its
> address and it isn't an lvalue.
> SE says: zork() is the name of a struct foo, so you CAN take its address.

You're right, the SE is wrong.

zork() is not exactly a "constant", but it is an expression of type struct
foo. However, it is *not* an lvalue so you cannot take its address.  Since
it is a structure expression, you can select a member (you do not have
to have an lvalue to do a member selection, even though many compilers
prevent you from selecting a member from a non-lvalue struct). Try this
expression on for size:

    struct foo func1(), func2();
    int i;
    
    (i ? func1() : func2()).mids;
----
Shankar Unni.
Hewlett-Packard California Language Lab.