Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

lvalue access rules and access to union members

4 views
Skip to first unread message

Jun Woong

unread,
Aug 29, 2001, 1:23:50 AM8/29/01
to
The current wording of C99 seems to run in contradiction.

extern void f2(int);
struct t1 { int member; } o_t1;
struct t2 { int member; };

void f(struct t1 *t1, struct t2 *t2)
{
t1->member = 18;
t2->member = 20;

f2(t1->member);
}

// ...

f(&o_t1, (struct t2 *)&o_t1);

The lvalue access rules (6.5p7) make the program above invalid, since
a conforming implementation is allowed to optimize the call to f2()
as f2(18).


But the Standard says the following is strictly conforming in its
example (the declaration of the union is visible).

// delcaration for struct t1, struct t2 and f2()

union {
struct t1 o_t1;
struct t2 o_t2;
} u;

// definition for f() ...

u.o_t1.member = 0;
f(&(u.o_t1), &(u.o_t2));

But, it still seems to be invalid to me, because the lvalue access
rules don't permit the accesses *within* f():

] An object shall have its stored value accessed only by an lvalue
] expression that has one of the following types: 73)
] . a type compatible with the effective type of the object,
] . a qualified version of a type compatible with the effective type
] of the object,
] . a type that is the signed or unsigned type corresponding to the
] effective type of the object,
] . a type that is the signed or unsigned type corresponding to a
] qualified version of the effective type of the object,
] . an aggregate or union type that includes one of the aforementioned
] types among its members (including, recursively, a member of a
] subaggregate or contained union), or
] . a character type.

The access in f() does not match any of those items (note that the
committee said before, "the lvalue access rules are additional
restriction not permission"), but the intent of the Standard is that
the example is strictly conforming. So I think, some wording that
makes the accesses as above valid should be added in 6.5p7.

Am I missing something here?

--
Jun Woong (myco...@hanmail.net)
Dept. of Physics, Univ. of Seoul

Clive D. W. Feather

unread,
Aug 30, 2001, 3:16:16 AM8/30/01
to
In article <G%_i7.1992$T4.1...@www.newsranger.com>, Jun Woong
<myco...@hanmail.net> writes

>But, it still seems to be invalid to me, because the lvalue access
>rules don't permit the accesses *within* f():
>
>] An object shall have its stored value accessed only by an lvalue
>] expression that has one of the following types: 73)
[...]

The object (u.t1.member) has type int and is being accessed through an
lvalue (t1->member, t2->member) with type int.

--
Clive D.W. Feather, writing for himself | Home: <cl...@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax) | Work: <cl...@demon.net>
Written on my laptop; please observe the Reply-To address

Jun Woong

unread,
Aug 31, 2001, 12:14:14 AM8/31/01
to
>In article <G%_i7.1992$T4.1...@www.newsranger.com>, Jun Woong <myco...@hanmail.net> writes
>>But, it still seems to be invalid to me, because the lvalue access
>>rules don't permit the accesses *within* f():
>>
>>] An object shall have its stored value accessed only by an lvalue
>>] expression that has one of the following types: 73)
>[...]
>
>The object (u.t1.member) has type int and is being accessed through an
>lvalue (t1->member, t2->member) with type int.
>

I don't think so. That's not a so simple issue. If your interpretation
is right, is the following programs both strictly conforming?

#1

struct t1 { int i; } t1;
struct t2 { int i; double d; };

void f(struct t1 *t1, struct t2 *t2)
{

t1->i = 1;
t2->i = 2;
g(t1->i);
}

..
f(&t1, (struct t2 *)&t1); /* line A */


#2

int *pi;
struct t1 { int i; double d; };

void f(struct t1 *t1)
{
t1->i = 1;
g(t1->i);
}

..
pi = malloc(sizeof(int));
f((struct t1 *)pi); /* line B */


In line A and B, the conversion is well-defined because there is no
alignment problem. Within f(), all the accesses are done through
lvalue of type int. But I know a DR that says the accesses have not
well-defined behavior, thus not strictly conforming. Without violation
of lvalue access rules, how can I interpret the result? Thus, I guess
the lvalue access rules should be applied to the cases as below:

t1->i = 1;

This access is composed of two accesses.
1) access through lvalue of type struct t1
2) access through lvalue of type int

If this access is only an access through lvalue of type int, we can't
have a way to explain the committee's answer in the DR, I think:

[cited from DR073]

] Response
]
] Lines A, B, C. The identifier array points to an object that is not
] large enough to hold two struct complex objects. The dot selection
] operator is at liberty to require the complete structure denoted by
] its left hand side to be accessed. Such an access would result in
] undefined behavior.

Please point out my mistake, if any.

Thanks in advance.

Clive D. W. Feather

unread,
Sep 3, 2001, 1:05:38 PM9/3/01
to
In article <qaEj7.4$F4...@www.newsranger.com>, Jun Woong
<myco...@hanmail.net> writes

>>The object (u.t1.member) has type int and is being accessed through an
>>lvalue (t1->member, t2->member) with type int.
>
>I don't think so. That's not a so simple issue. If your interpretation
>is right, is the following programs both strictly conforming?

[...]

I think the issue is complex enough to require a formal response from
WG14. For that reason I've submitted a potential DR, and I'm going to
wait for a response before commenting further.

0 new messages