Function-returned structures

KLH at sri-nic.arpa KLH at sri-nic.arpa
Sun Feb 8 09:37:56 AEST 1987


OK, I have a question that I haven't been able to satisfactorily answer
after poring through both H&S and the 6/87 ANSI draft, so I'll try this
group.

The problem has to do with selecting components from structures
returned by functions, and the question is "can you select an array?".
Many C operators have a constraint that their operand(s) be an lvalue,
and a simple check for this helps the compiler catch many of the
meaningless constructs that a user might attempt.  However, a
structure returned by a function is NOT an lvalue, yet component
selection is explicitly permitted for this case.  At first glance this
might seem straightforward, but it turns out that if you permit
array-type members to be selected, it is more like opening a trapdoor.

Here's an illustration.  Given:
	struct s { int x; int a[10]; };	/* The structure */
	struct s f();			/* The function returning it */
	int i, *ip;			/* Bit players */

Then a "typical" example of
	i = f().x;		/* Legal and makes sense. */
is explicitly permitted.  What I haven't been able to figure out is whether
something like
	i = f().a[i];		/* Looks plausible, whether legal or not. */
should also be permitted.  The wording of both ANSI and H&S implies that it
is, and I can't find anything to do with lvalue-ness or array-to-pointer
conversion that would prohibit it.  But if you accept this case, then you
are allowed to create pointers to structures (or structure components)
returned by such functions.  After all,
	i = *(f().a + i);	/* is "precisely equivalent" to f().a[i] */
	ip = f().a;		/* therefore f().a is a valid expression */
				/* although it is pretty nonsensical */

But the whole point of making the function result a non-lvalue is so
you cannot refer to it in this way!  &(f().x) for example is illegal.
There seems to be some inconsistency here, and I'm not sure how to
resolve it.  I'm not so worried about the user screwing up (there are
plenty of other ways to accomplish this) as I am about making sure my
compiler has both a definite way of knowing whether a construct is
legal, and a way of implementing it if it is.  (Incidentally, 4.3BSD C
won't even accept f().x)

Comments?
-------



More information about the Comp.lang.c mailing list