K
Keith Thompson
CBFalconer said:But what if you have a function f that takes two (struct s)s as
parameters. You want to write:
f(g(1).a, g(2).b)
(remember that the limitation is against using sub-portions of
those returned structures). I maintain you should write:
gv1 = g(1); gv2 = g(2);
f(gv1.a, gv2.b);
and nobody is confused, including the compiler.
You're being a bit unclear on what the types of gv1, gv2, f(), and g()
are. Given the code you presented, I think that there have to be two
struct types. If f() takes two arguments of type struct s, the g must
return a result of type, let's say, struct t, which has two members of
type struct s, called a and b.
Adding these declarations, here's a complete program that's consistent
with your code snippet. It's a bit more vertically compressed than my
usual style. In practice, both structs could have more members.
#include <stdio.h>
struct s { int x; };
struct t { struct s a; struct s b; };
void f(struct s arg1, struct s arg2) {
printf("%d %d\n", arg1.x, arg2.x);
}
struct t g(int n) {
struct t result;
result.a.x = n;
result.b.x = n + 1;
return result;
}
int main(void) {
f(g(1).a, g(2).b);
return 0;
}
Are you saying that, *as a matter of programming style*, it would be
better to assign the values returned by g() to temporaries before
passing their members to f()? If so, I'm not necessarily going to
disagree. But it really has nothing to do with what's being
discussed. This code is perfectly valid and unambiguous, and has been
at least since C89. I'd be surprised if any compiler were "confused"
by it. There are no arrays (ignoring the format string), and no
function results or parts thereof used as lvalues.
Using a member of a struct value returned by a function is already
legal, and is not the problem we're discussing.
If you're suggesting that an implementation should be allowed to
reject or mis-handle this code, then you're suggesting a change that
would break existing C90 and C99 code. (I don't believe you really
mean that.)
This whole discussion isn't about programming style, it's about what
the language requires compilers to implement. And it's about a very
specific case, a function returning a struct or union that has an
array member, and a caller that refers to that array member within the
expression containing the call. If you want to make a relevant point,
you're going to have to use a relevant example -- and I'd appreciate
it if you'd provide any necessary declarations so we don't have to
reconstruct them.