Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!rutgers!brl-adm!adm!KLH@sri-nic.arpa From: KLH@sri-nic.arpa Newsgroups: comp.lang.c Subject: Function-returned structures Message-ID: <4319@brl-adm.ARPA> Date: Sat, 7-Feb-87 18:37:56 EST Article-I.D.: brl-adm.4319 Posted: Sat Feb 7 18:37:56 1987 Date-Received: Sun, 8-Feb-87 07:43:31 EST Sender: news@brl-adm.ARPA Lines: 44 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? -------