Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #101118 > unrolled thread
| Started by | Manfred <noname@invalid.add> |
|---|---|
| First post | 2017-01-04 19:46 +0100 |
| Last post | 2017-01-30 12:05 -0800 |
| Articles | 20 on this page of 78 — 13 participants |
Back to article view | Back to comp.lang.c
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: lvalues from the ternary op Manfred <noname@invalid.add> - 2017-01-04 19:46 +0100
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-04 11:08 -0800
Re: lvalues from the ternary op Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-04 21:10 +0000
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-04 13:48 -0800
Re: lvalues from the ternary op Ian Collins <ian-news@hotmail.com> - 2017-01-05 11:07 +1300
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-04 14:20 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-04 14:41 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-04 15:21 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-04 15:52 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-04 16:37 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-04 18:31 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-13 17:26 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-13 17:49 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-15 22:53 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-13 17:08 -0800
Re: lvalues from the ternary op Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-14 02:15 +0000
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-15 22:51 -0800
Re: lvalues from the ternary op luser droog <luser.droog@gmail.com> - 2017-01-16 23:09 -0800
Re: lvalues from the ternary op Manfred <noname@invalid.add> - 2017-01-18 14:51 +0100
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-18 09:59 -0800
Re: lvalues from the ternary op Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2017-01-18 13:12 -0500
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-18 12:11 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-18 12:45 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-18 14:07 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-18 14:40 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-18 16:10 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-18 18:08 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-19 06:44 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-19 08:40 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-19 12:32 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-20 06:01 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-20 08:15 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-20 10:51 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-20 11:32 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-20 13:41 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-23 07:04 -0800
Re: lvalues from the ternary op Ike Naar <ike@iceland.freeshell.org> - 2017-01-23 17:59 +0000
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-23 10:57 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-31 08:45 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-01-31 09:13 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-31 10:17 -0800
Re: lvalues from the ternary op Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-01 01:51 +0000
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-01 14:24 -0800
Re: lvalues from the ternary op Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-02 03:07 +0000
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-04 04:43 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-04 08:01 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-09 09:06 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-09 11:56 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-12 10:29 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-12 13:43 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-19 21:44 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-20 08:15 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-24 07:58 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-24 10:00 -0800
Re: lvalues from the ternary op scott@slp53.sl.home (Scott Lurndal) - 2017-02-24 18:58 +0000
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-24 13:03 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-02-24 14:11 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-02-24 12:42 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-02-24 13:49 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-24 13:58 -0800
Re: lvalues from the ternary op Keith Thompson <kst-u@mib.org> - 2017-02-24 14:56 -0800
Re: lvalues from the ternary op supercat <flatfinger@casperkitty.com> - 2017-02-25 14:00 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-25 09:23 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-25 09:43 -0800
Re: lvalues from the ternary op Kelsey Bjarnason <kbjarnason@gmail.com> - 2017-02-01 22:47 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-02 10:12 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-04 07:51 -0800
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-02-04 08:18 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-09 08:58 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-04 04:00 -0800
Re: lvalues from the ternary op Kelsey Bjarnason <kbjarnason@gmail.com> - 2017-02-04 09:35 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-04 09:35 -0800
Re: lvalues from the ternary op Robert Wessel <robertwessel2@yahoo.com> - 2017-01-31 13:36 -0600
Re: lvalues from the ternary op supercat@casperkitty.com - 2017-01-31 12:23 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-02-01 13:48 -0800
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-31 08:53 -0800
Re: lvalues from the ternary op Manfred <noname@invalid.add> - 2017-01-19 14:10 +0100
Re: lvalues from the ternary op Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-30 12:05 -0800
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2017-01-18 13:12 -0500 |
| Message-ID | <o5ob3k$l4a$2@dont-email.me> |
| In reply to | #102137 |
On Wednesday January 18 2017 12:59, in comp.lang.c, "Keith Thompson" <kst-
u@mib.org> wrote:
> Manfred <noname@invalid.add> writes:
>> On 1/17/2017 8:09 AM, luser droog wrote:
>>> FWIW, my conception of an lvalue is slightly different. To me it
>>> is "a thing which can be on the left of an assignment operator".
>> This is the same definition that appeared in Dennis Ritchie's "C
>> Reference Manual" from Bell Labs.
>
> That is of course an incomplete definition. There are plenty of
> lvalues that can't appear on the LHS of an assignment, including
> array names and names of const-qualified objects. Nevertheless that
> is the origin of the "L" in "lvalue", and it's a good mnemonic.
>
> BTW, the 1974 and 1975 editions of the C Reference Manual both say:
>
> An object is a manipulatable region of storage; an lvalue is an
> expression referring to an object. An obvious example of an lvalue
> expression is an identifier.
>
> I'll check K&R1 later today.
My copy of K&R1 says the same, in Appendix A ("C Reference Manual")
"The C Programming Language" (Brian W. Kernighan * Dennis M. Ritchie)
(c) 1978, Bell Telephone Laboratories
[snip]
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-18 12:11 -0800 |
| Message-ID | <5ff45dfe-0bd4-479b-a017-64da7de9ae0d@googlegroups.com> |
| In reply to | #102137 |
On Wednesday, January 18, 2017 at 11:59:18 AM UTC-6, Keith Thompson wrote: > BTW, the 1974 and 1975 editions of the C Reference Manual both say: > > An object is a manipulatable region of storage; an lvalue is an > expression referring to an object. An obvious example of an lvalue > expression is an identifier. Did bitfields exist in either of those? Otherwise, it would seem that lvalues would be expressions that can have their address taken. > I've discussed this at greater length here: > https://github.com/Keith-S-Thompson/the-flat-trantor-society/blob/master/005-c-standard-quibbles.md#what-is-an-lvalue I don't think I'd seen that paper before. It looks nice. I don't think there word "potential" should be seen a problem in that context, though I think it might be better to say that an lvalue represents a "view" of a potential object. A successful malloc(1000) creates a single object, and while code may create many views of different parts of it, that doesn't make each view "an object".
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-18 12:45 -0800 |
| Message-ID | <ln4m0whzbs.fsf@kst-u.example.com> |
| In reply to | #102149 |
supercat@casperkitty.com writes:
> On Wednesday, January 18, 2017 at 11:59:18 AM UTC-6, Keith Thompson wrote:
>> BTW, the 1974 and 1975 editions of the C Reference Manual both say:
>>
>> An object is a manipulatable region of storage; an lvalue is an
>> expression referring to an object. An obvious example of an lvalue
>> expression is an identifier.
>
> Did bitfields exist in either of those? Otherwise, it would seem that
> lvalues would be expressions that can have their address taken.
Bit fields didn't, but `register` did, with a statement that the "&"
operator cannot be applied to a register object.
I think that saying that an lvalue refers to an object is more than
clear enough. `x` is an lvalue, `x+1` is not. Unary "&" requires an
lvalue, but not all lvalues can have unary "&" applied to them, just as
not all lvalues can be on the LHS of an assignment. The definition
describes what an lvalue is rather than what you can do with it.
>> I've discussed this at greater length here:
>> https://github.com/Keith-S-Thompson/the-flat-trantor-society/blob/master/005-c-standard-quibbles.md#what-is-an-lvalue
>
> I don't think I'd seen that paper before. It looks nice. I don't think
> there word "potential" should be seen a problem in that context, though I
> think it might be better to say that an lvalue represents a "view" of a
> potential object. A successful malloc(1000) creates a single object, and
> while code may create many views of different parts of it, that doesn't
> make each view "an object".
I'm not at all sure what point you're making here.
The word "potentially" was added to make it clear that *ptr is an lvalue
even if ptr's value happens (at run time) to be a null pointer, or some
other pointer value that cannot validly be dereferenced.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-18 14:07 -0800 |
| Message-ID | <5e9cc790-7d79-4ce3-8101-0d423e8f2a46@googlegroups.com> |
| In reply to | #102150 |
On Wednesday, January 18, 2017 at 2:45:36 PM UTC-6, Keith Thompson wrote:
> > I don't think I'd seen that paper before. It looks nice. I don't think
> > there word "potential" should be seen a problem in that context, though I
> > think it might be better to say that an lvalue represents a "view" of a
> > potential object. A successful malloc(1000) creates a single object, and
> > while code may create many views of different parts of it, that doesn't
> > make each view "an object".
>
> I'm not at all sure what point you're making here.
>
> The word "potentially" was added to make it clear that *ptr is an lvalue
> even if ptr's value happens (at run time) to be a null pointer, or some
> other pointer value that cannot validly be dereferenced.
I understood your use of the term "potential", but you seemed uneasy
about it. I see no reason for any unease.
A bigger issue is that an lvalue isn't really "an object", but rather a
view. Given at file scope, what objects are created by:
struct { uint32_t x, y; } s1;
union { uint32_t x; double y; } u1;
I would say those declarations would create two objects, s1 and s2.
The lvalue s1 would be a view of all eight bytes of storage occupied by s1;
s1.x would be a view of the first four bytes of that, and s1.y would be
a view of the other four bytes. Likewise u1 would be a view of the eight
bytes occupied by u1, u1.x would be a view of the first four bytes, and
u1.y would be a view of all eight bytes.
If an lvalue is defined as a view, then the effect of "." becomes straight-
forward: given a view to a region of storage, yield a view to a subset of
that storage. Describing the effect in terms of "objects" would be less
clear, since it would require a structure and union definitions each create
multiple overlapping objects.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-18 14:40 -0800 |
| Message-ID | <lnziiogffd.fsf@kst-u.example.com> |
| In reply to | #102160 |
supercat@casperkitty.com writes:
> On Wednesday, January 18, 2017 at 2:45:36 PM UTC-6, Keith Thompson wrote:
>> > I don't think I'd seen that paper before. It looks nice. I don't think
>> > there word "potential" should be seen a problem in that context, though I
>> > think it might be better to say that an lvalue represents a "view" of a
>> > potential object. A successful malloc(1000) creates a single object, and
>> > while code may create many views of different parts of it, that doesn't
>> > make each view "an object".
>>
>> I'm not at all sure what point you're making here.
>>
>> The word "potentially" was added to make it clear that *ptr is an lvalue
>> even if ptr's value happens (at run time) to be a null pointer, or some
>> other pointer value that cannot validly be dereferenced.
>
> I understood your use of the term "potential", but you seemed uneasy
> about it. I see no reason for any unease.
I'm uneasy because I don't think it's entirely clear what it means.
If you're already aware of the particular issue (*ptr where ptr may
or may not be dereferenceable), it's probably fairly obvious that
the added word was meant to address it, but if you're not, it might
not be clear what "potentially designates" means. I had hoped, when
I made the suggestion, that the committee would add some wording at
least informally explaining what "potentially" means in that context.
> A bigger issue is that an lvalue isn't really "an object", but rather a
> view.
No, an lvalue is not an object, and nobody ever said it was.
An lvalue is a kind of expression. As such, it is an entity that exists
in C source code, before any objects yet exist.
> Given at file scope, what objects are created by:
>
> struct { uint32_t x, y; } s1;
> union { uint32_t x; double y; } u1;
>
> I would say those declarations would create two objects, s1 and s2.
>
> The lvalue s1 would be a view of all eight bytes of storage occupied by s1;
> s1.x would be a view of the first four bytes of that, and s1.y would be
> a view of the other four bytes. Likewise u1 would be a view of the eight
> bytes occupied by u1, u1.x would be a view of the first four bytes, and
> u1.y would be a view of all eight bytes.
s1, s1.x, s1.y, u1, u1.x, and u1.y are all objects. If you disagree,
see the standard's definition of "object", and explain how any of them
doesn't qualify. I'm using "s1" as the name of the struct object
created by the declaration, not using "s1" as an expression; likewise
for the others.
> If an lvalue is defined as a view, then the effect of "." becomes straight-
> forward: given a view to a region of storage, yield a view to a subset of
> that storage. Describing the effect in terms of "objects" would be less
> clear, since it would require a structure and union definitions each create
> multiple overlapping objects.
But structure and union definitions *do* create multiple overlapping
objects. Introducing this idea of a "view" is neither necessary nor
helpful.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-18 16:10 -0800 |
| Message-ID | <cff83e51-e23c-417d-a719-610db57062d6@googlegroups.com> |
| In reply to | #102162 |
On Wednesday, January 18, 2017 at 4:39:58 PM UTC-6, Keith Thompson wrote:
> But structure and union definitions *do* create multiple overlapping
> objects. Introducing this idea of a "view" is neither necessary nor
> helpful.
The C Standard doesn't really cope well with the existence of multiple
overlapping objects. It is helpful to have a concept to describe a region
of storage with a well-defined lifetime which is disjoint from all other
such regions. It is also useful to have a concept to describe a view of
a region of storage whose lifetime may be shorter than that of the storage
thus described, and which can only overlap other "live" views in limited
circumstances. Using the same term to describe both concepts, however,
seems less helpful.
Given struct s { uint32_t x,y;} *p1,*p2; in what cases, if any, would a
compiler be allowed to assume that p1->x and p2->y cannot alias? What
would justify such an assumption? From what I can tell, existing compilers
do optimize based on such an assumption, and I think the Standard is
probably intended to allow it (it's generally a useful optimization) but
what exactly is or isn't allowed is rather unclear.
If one regards the expression p1->x as creating a view of the storage
occupied thereby, and says that if multiple operations are performed on
p1->x without anything happening between them to suggest the possibility
of outside accesses, those multiple accesses may be regarded as using the
same active view [if intervening actions would suggest the possibility of
outside accesses, each access would use its own view]. Aliasing rules could
then be summed up by saying that no storage while be modified at any time
when multiple unrelated active views exist to it.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-18 18:08 -0800 |
| Message-ID | <lnmvenhkck.fsf@kst-u.example.com> |
| In reply to | #102167 |
supercat@casperkitty.com writes:
> On Wednesday, January 18, 2017 at 4:39:58 PM UTC-6, Keith Thompson wrote:
>> But structure and union definitions *do* create multiple overlapping
>> objects. Introducing this idea of a "view" is neither necessary nor
>> helpful.
>
> The C Standard doesn't really cope well with the existence of multiple
> overlapping objects.
Sure it does, at least for the purposes of what we're discussing at the
moment.
Given:
struct { uint32_t x, y; } s1;
s1, s1.x, and s1.y are all objects. Again, if you disagree, consult the
standard's definition of the word "object" and explain how it doesn't
apply to all three of them. And if s1.x isn't an object, that's going
to break a lot of the existing wording in the standard.
> It is helpful to have a concept to describe a region
> of storage with a well-defined lifetime which is disjoint from all other
> such regions.
In other words, an object that's not part of another object. Perhaps it
would be helpful in some contexts -- but the Standard copes perfectly
well, as far as I can tell, without a specific term for that concept.
If you want a term for it, I suppose "full object" would do, by analogy
with the existing terms "full expression" and "full declarator".
> It is also useful to have a concept to describe a view of
> a region of storage whose lifetime may be shorter than that of the storage
> thus described, and which can only overlap other "live" views in limited
> circumstances. Using the same term to describe both concepts, however,
> seems less helpful.
>
> Given struct s { uint32_t x,y;} *p1,*p2; in what cases, if any, would a
> compiler be allowed to assume that p1->x and p2->y cannot alias?
In this context, I don't care. The question of whether a given
expression is an lvalue or not isn't about aliasing. I see no point in
bringing in irrelevant complications.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-19 06:44 -0800 |
| Message-ID | <09829387-6df4-4cc8-a044-e71b7f8d44dd@googlegroups.com> |
| In reply to | #102170 |
On Wednesday, January 18, 2017 at 8:08:30 PM UTC-6, Keith Thompson wrote:
> supercat writes:
> > The C Standard doesn't really cope well with the existence of multiple
> > overlapping objects.
>
> Sure it does, at least for the purposes of what we're discussing at the
> moment.
>
> Given:
>
> struct { uint32_t x, y; } s1;
>
> s1, s1.x, and s1.y are all objects. Again, if you disagree, consult the
> standard's definition of the word "object" and explain how it doesn't
> apply to all three of them. And if s1.x isn't an object, that's going
> to break a lot of the existing wording in the standard.
Okay, now let's add a little more. Assume normal headers and struct layout,
and that code is within a function.
struct s { uint32_t x, y, z; };
char *p = calloc(1,1000);
struct s *ps1 = (struct s*)p;
struct s *ps2 = (struct s*)(p+4);
struct s *ps3 = (struct s*)(p+8);
ps1->y = 3;
ps2->x = 5;
ps2->y = 9;
At that point, what objects *exist*? Is ps1->x an object? How about
ps1->y? Is *ps3 an object? Maybe your understanding of the rules makes
it clear what objects exist, but mine doesn't. Perhaps you can enlighten
me.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-19 08:40 -0800 |
| Message-ID | <lninpbgfz8.fsf@kst-u.example.com> |
| In reply to | #102178 |
supercat@casperkitty.com writes:
> On Wednesday, January 18, 2017 at 8:08:30 PM UTC-6, Keith Thompson wrote:
>> supercat writes:
>> > The C Standard doesn't really cope well with the existence of multiple
>> > overlapping objects.
>>
>> Sure it does, at least for the purposes of what we're discussing at the
>> moment.
>>
>> Given:
>>
>> struct { uint32_t x, y; } s1;
>>
>> s1, s1.x, and s1.y are all objects. Again, if you disagree, consult the
>> standard's definition of the word "object" and explain how it doesn't
>> apply to all three of them. And if s1.x isn't an object, that's going
>> to break a lot of the existing wording in the standard.
>
> Okay, now let's add a little more.
Let's not.
[snip]
> At that point, what objects *exist*?
[snip]
You haven't addressed the question of whether s1, s1.x, and s1,y are
objects, and I don't see how anything in your latest post has anything
to do with the meaning of "lvalue". You are adding unnecessarily and
irrelevant complications.
If you won't address my points, I'll return the favor.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-19 12:32 -0800 |
| Message-ID | <9d2313c9-902c-45a2-8d3a-60fb168bcb0d@googlegroups.com> |
| In reply to | #102183 |
On Thursday, January 19, 2017 at 10:41:05 AM UTC-6, Keith Thompson wrote:
> supercat writes:
> > Okay, now let's add a little more.
>
> Let's not.
>
> [snip]
> > At that point, what objects *exist*?
> [snip]
>
> You haven't addressed the question of whether s1, s1.x, and s1,y are
> objects, and I don't see how anything in your latest post has anything
> to do with the meaning of "lvalue". You are adding unnecessarily and
> irrelevant complications.
>
> If you won't address my points, I'll return the favor.
It is possible to evaluate an lvalue of type T, and have it yield something
that can be used as an object of type T, without any object of type T having
previously existed. Unless the creation of such an object were back-dated
to the creation of the underlying storage, that would imply that the lifetime
of the things yielded by lvalues need not match the lifetime of the
underlying storage.
Given:
void *p = calloc(1,1234);
float *fp = p;
uint16_t *hp = p;
unsigned char *cp = p;
double d = *fp;
*fp = 1.25f
*hp = 0x1234;
cp[0]++;
cp[1]++;
for (int i=0; i<4; i++)
printf("%02X", cp[i]);
free(p);
If no objects of type "float" existed anywhere in the universe before the
above code was executed, what "float" objects would exist during its
execution, and what would their lifetimes be? By what means would the
lifetimes of the objects in question be defined?
C defines rules for the lifetimes of compiler- or library-allocated chunks
of storage that are disjoint from all other such chunks (my first
definition of object). Evaluation of lvalue expressions often yields
things whose usable lifetime may be less than that of the containing
object. How does that not imply that the result of an lvalue expression
is a different kind of thing from the the disjoint regions of storage
whose lifetimes are described by the Standard?
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-20 06:01 -0800 |
| Message-ID | <734bc6bf-9879-4e71-9f54-f27ec92fb50e@googlegroups.com> |
| In reply to | #102183 |
On Thursday, January 19, 2017 at 10:41:05 AM UTC-6, Keith Thompson wrote: > You haven't addressed the question of whether s1, s1.x, and s1,y are > objects, and I don't see how anything in your latest post has anything > to do with the meaning of "lvalue". You are adding unnecessarily and > irrelevant complications. > > If you won't address my points, I'll return the favor. Short answer: s1.x and u1.x will behave as objects when they are used. When they are not being used, they need not be treated as an objects. If an implementation defines the effect of writing a union member of one type and reading a member of another type, and if both members of a union continually exist as objects throughout the lifetime of that union, those together would imply that taking the address of each member and later using it to access that member would be treated as accessing an object with a pointer of the proper type.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-20 08:15 -0800 |
| Message-ID | <ln8tq5hfmj.fsf@kst-u.example.com> |
| In reply to | #102228 |
supercat@casperkitty.com writes:
> On Thursday, January 19, 2017 at 10:41:05 AM UTC-6, Keith Thompson wrote:
>> You haven't addressed the question of whether s1, s1.x, and s1,y are
>> objects, and I don't see how anything in your latest post has anything
>> to do with the meaning of "lvalue". You are adding unnecessarily and
>> irrelevant complications.
>>
>> If you won't address my points, I'll return the favor.
>
> Short answer: s1.x and u1.x will behave as objects when they are used. When
> they are not being used, they need not be treated as an objects.
I have a much shorter and more accurate answer.
s1.x and u1.x are objects.
And as expressions, s1.x and u1.x are lvalues.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-20 10:51 -0800 |
| Message-ID | <2f20253f-9ce6-4dcd-82e7-2fcdc2eae5b0@googlegroups.com> |
| In reply to | #102239 |
On Friday, January 20, 2017 at 10:14:23 AM UTC-6, Keith Thompson wrote:
> I have a much shorter and more accurate answer.
>
> s1.x and u1.x are objects.
Is the term "object" supposed to have the same meaning when applied to the
result of the pointer indirection operator as when applied to lvalues that
refer to declared variables of automatic or static duration?
If u1.x and u1.y are objects which exist continuously as long as u1 exists,
then given pointers px and py of the appropriate types set to &(u1.x) and
&(u1.y), the lvalues *px and u1.x should be equivalent, and likewise the
lvalues *py and u2.y, correct?
Would such an interpretation be consistent with the behavior of compilers
that define the effect of writing u1.x and reading u1.y, but don't apply
the same treatment to code which writes *px and reads *py? Which of the
following statements would best apply:
1. The lvalue expression of u1.x sometimes does something other than
treat a pre-existing object as an lvalue.
2. The lvalue expression *px may sometimes do something other than
treat a pre-existing object as an lvalue, even if px==&u1.x.
3. The object yielded by lvalue expression u1.x may be somehow different
from the object yielded by *px, even when px==&u1.x.
4. Some other explanation for the behavior?
Which of the above do you think best justifies compiler behavior?
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-20 11:32 -0800 |
| Message-ID | <ln1svxh6i1.fsf@kst-u.example.com> |
| In reply to | #102252 |
supercat@casperkitty.com writes:
> On Friday, January 20, 2017 at 10:14:23 AM UTC-6, Keith Thompson wrote:
>> I have a much shorter and more accurate answer.
>>
>> s1.x and u1.x are objects.
>
> Is the term "object" supposed to have the same meaning when applied to the
> result of the pointer indirection operator as when applied to lvalues that
> refer to declared variables of automatic or static duration?
>
> If u1.x and u1.y are objects which exist continuously as long as u1 exists,
> then given pointers px and py of the appropriate types set to &(u1.x) and
> &(u1.y), the lvalues *px and u1.x should be equivalent, and likewise the
> lvalues *py and u2.y, correct?
What on Earth are you talking about?
An "object" is by definition a "region of data storage in the
execution environment, the contents of which can represent values".
(I've encouraged you several times to consult this definition.)
s1.x and u1.x are objects. (I'm referring to the entities that
"s1.x" and "u1.x" refer to, not to `s1.x` and `u2.x` as expressions;
as expressions, both are clearly lvalues.) Do you disagree?
There are probably some issues involving aliasing, but I don't
believe any such issues are relevant to the question of whether a
given expression is or is not an lvalue.
> Would such an interpretation be consistent with the behavior of compilers
> that define the effect of writing u1.x and reading u1.y, but don't apply
> the same treatment to code which writes *px and reads *py? Which of the
> following statements would best apply:
>
> 1. The lvalue expression of u1.x sometimes does something other than
> treat a pre-existing object as an lvalue.
What does it mean to "treat an object as an lvalue"? An lvalue is a
kind of expression, something that exists in C source code. An object
is a region of data storage, something that exists during program
execution.
[snip]
I think you're saying something about aliasing, or about the so-called
strict aliasing rules. It's not something I care to comment on at the
moment.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-20 13:41 -0800 |
| Message-ID | <1de271ed-727b-4843-92ba-5487603c3fa4@googlegroups.com> |
| In reply to | #102256 |
On Friday, January 20, 2017 at 1:31:42 PM UTC-6, Keith Thompson wrote: > An "object" is by definition a "region of data storage in the > execution environment, the contents of which can represent values". > (I've encouraged you several times to consult this definition.) > s1.x and u1.x are objects. (I'm referring to the entities that > "s1.x" and "u1.x" refer to, not to `s1.x` and `u2.x` as expressions; > as expressions, both are clearly lvalues.) Do you disagree? The point of contention is "can represent values". Any region of length N, with N>2, will contain N(N+1)/2-1 shorter regions that can represent values. While I suppose one could say that a successful malloc(12) returns 78 objects (one of length 12, two of length 11, etc.) I don't think would be particularly helpful. It would be more helpful to recognize "can represent values of a particular type". Further, if a union contains two structures, whose first three members match, but which differ in the rest of their members, would the fourth member of the second struct be something which "can represent values" while the first structure is the active member of the union? > There are probably some issues involving aliasing, but I don't > believe any such issues are relevant to the question of whether a > given expression is or is not an lvalue. In any defined situation where a region of storage is employed as an lvalue of some type, that region will need to be or become capable of representing values of that type for purposes of the access, regardless of whether it had been capable of doing so previously. In the absence of aliasing rules, any region would be capable of representing values of any type which was compatible with its size and alignment. New objects would be created with malloc() or by entering blocks with automatic variables, and objects would be destroyed with free() or by exiting blocks with automatic variables. Aliasing rules, however, create vastly more complicated rules for "can represent values"; if something can only be a regarded as an object of a given type if it can represent values of that type, then the set of objects will change as storage regions acquire or lose the ability to represent values of different types. > > Would such an interpretation be consistent with the behavior of compilers > > that define the effect of writing u1.x and reading u1.y, but don't apply > > the same treatment to code which writes *px and reads *py? Which of the > > following statements would best apply: > > > > 1. The lvalue expression of u1.x sometimes does something other than > > treat a pre-existing object as an lvalue. > > What does it mean to "treat an object as an lvalue"? An lvalue is a > kind of expression, something that exists in C source code. An object > is a region of data storage, something that exists during program > execution. Substitute "yield an existing object". > I think you're saying something about aliasing, or about the so-called > strict aliasing rules. It's not something I care to comment on at the > moment. Without aliasing rules, the original definition of "object" would be just fine. The problem is that the definition was written at a time when the set of ways in which a region of storage could be represent combinations of objects of different types would be constant throughout that region's lifetime.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-23 07:04 -0800 |
| Message-ID | <aa4dec3a-ebfc-495a-9160-e260037473f5@googlegroups.com> |
| In reply to | #102256 |
On Friday, January 20, 2017 at 1:31:42 PM UTC-6, Keith Thompson wrote:
> An "object" is by definition a "region of data storage in the
> execution environment, the contents of which can represent values".
> (I've encouraged you several times to consult this definition.)
> s1.x and u1.x are objects. (I'm referring to the entities that
> "s1.x" and "u1.x" refer to, not to `s1.x` and `u2.x` as expressions;
> as expressions, both are clearly lvalues.) Do you disagree?
Given "union u { uint32_t x; float y; } u;", if both u.x and u.y are objects,
which of the following can be said about the code "u.x = 1;":
1. The thing to the left of the equals is something other than an
lvalue of type "uint32_t".
2. The code does not access the stored value of a "float" object.
3. The code invokes Undefined Behavior because it uses an lvalue of type
uint32_t to access the value of a float object.
I would regard possibility #3 as preposterous, since it would suggest that
any union which contained anything other than a combination of alias-
compatible types (e.g. int32_t and uint32_t) would be completely unusable
for any purpose.
In order to make unions workable *at all*, it's necessary to either adjust
the meaning of "lvalue" such that u.x is something other than a simple
lvalue of type "uint32_t", else adjust the meaning of "object" such that
u.y isn't considered an object while it's not the active member, or adjust
the meaning of "access the stored value" to suggest that "u.x = 1;" doesn't
access the stored value of the aforementioned u.y object.
Were it not for N1570 6.3(7), there would be no problem with straightforward
definitions of "object" and "lvalue". As it is, though, I can't see any way
to reconcile straightforward definitions of those terms with the rules as
written in a way that wouldn't make unions completely useless *even in cases
that don't involve aliasing*.
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2017-01-23 17:59 +0000 |
| Message-ID | <slrn3vfso8ch75.o08.ike@iceland.freeshell.org> |
| In reply to | #102373 |
On 2017-01-23, supercat@casperkitty.com <supercat@casperkitty.com> wrote:
> Given "union u { uint32_t x; float y; } u;", if both u.x and u.y are objects,
> which of the following can be said about the code "u.x = 1;":
>
> 1. The thing to the left of the equals is something other than an
> lvalue of type "uint32_t".
>
> 2. The code does not access the stored value of a "float" object.
>
> 3. The code invokes Undefined Behavior because it uses an lvalue of type
> uint32_t to access the value of a float object.
>
> I would regard possibility #3 as preposterous, since it would suggest that
> any union which contained anything other than a combination of alias-
> compatible types (e.g. int32_t and uint32_t) would be completely unusable
> for any purpose.
>
> In order to make unions workable *at all*, it's necessary to either adjust
> the meaning of "lvalue" such that u.x is something other than a simple
> lvalue of type "uint32_t", else adjust the meaning of "object" such that
> u.y isn't considered an object while it's not the active member, or adjust
> the meaning of "access the stored value" to suggest that "u.x = 1;" doesn't
> access the stored value of the aforementioned u.y object.
>
> Were it not for N1570 6.3(7), there would be no problem with straightforward
> definitions of "object" and "lvalue". As it is, though, I can't see any way
> to reconcile straightforward definitions of those terms with the rules as
> written in a way that wouldn't make unions completely useless *even in cases
> that don't involve aliasing*.
In my copy of N1570, 6.3 is about conversions, and there is no
6.3(7), so I'm not sure what you mean by that. Can you please quote
the text that you are referring to?
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-23 10:57 -0800 |
| Message-ID | <cf333488-04d3-4338-b02f-6d4c194b4e56@googlegroups.com> |
| In reply to | #102378 |
On Monday, January 23, 2017 at 12:01:20 PM UTC-6, Ike Naar wrote:
> On 2017-01-23, supercat wrote:
> > Given "union u { uint32_t x; float y; } u;", if both u.x and u.y are objects,
> > which of the following can be said about the code "u.x = 1;":
> >
> > 1. The thing to the left of the equals is something other than an
> > lvalue of type "uint32_t".
> >
> > 2. The code does not access the stored value of a "float" object.
> >
> > 3. The code invokes Undefined Behavior because it uses an lvalue of type
> > uint32_t to access the value of a float object.
> >
> > I would regard possibility #3 as preposterous, since it would suggest that
> > any union which contained anything other than a combination of alias-
> > compatible types (e.g. int32_t and uint32_t) would be completely unusable
> > for any purpose.
> >
> > In order to make unions workable *at all*, it's necessary to either adjust
> > the meaning of "lvalue" such that u.x is something other than a simple
> > lvalue of type "uint32_t", else adjust the meaning of "object" such that
> > u.y isn't considered an object while it's not the active member, or adjust
> > the meaning of "access the stored value" to suggest that "u.x = 1;" doesn't
> > access the stored value of the aforementioned u.y object.
> >
> > Were it not for N1570 6.3(7), there would be no problem with straightforward
> > definitions of "object" and "lvalue". As it is, though, I can't see any way
> > to reconcile straightforward definitions of those terms with the rules as
> > written in a way that wouldn't make unions completely useless *even in cases
> > that don't involve aliasing*.
>
> In my copy of N1570, 6.3 is about conversions, and there is no
> 6.3(7), so I'm not sure what you mean by that. Can you please quote
> the text that you are referring to?
Sorry--I meant 6.5(7) but probably erred when paging up to find out what
section it was.
7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:88)
-- 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 lvalue "u" would be a union, so "u = someOtherUnion;" would be allowed
even though the union contains objects of different types, but in the
statement "u.x = 1;", the left-hand operand of "=" would appear to be an
lvalue of type "uint32_t". For even the most basic of operations to work
with the rules as written, applying the "." operator to a union would have
to do something other than just yield an object of the member type.
From what I can tell, the authors of the Standard intended to allow the
pattern:
uint32_t *p = &(u.x);
*p = 3;
at least in cases where x is the active member of u. The Standard does not
define any way in which *p would be anything other than an lvalue of type
"uint32_t", and so the only way I can see that such action would be
allowable under the above rules would be if union members were only regarded
as objects while they are active.
Aliasing rules shouldn't need to require that union members be regarded
as being "objects" at some times but not others. With the rules as they
are, however, I see no way to keep a definition of "object" which would
imply that union members are objects with the same lifetime as the union,
without excessively and needlessly restricting the semantics of the
language even in cases that don't involve aliasing.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-01-31 08:45 -0800 |
| Message-ID | <kfnlgtrdvq3.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #102373 |
supercat@casperkitty.com writes:
> On Friday, January 20, 2017 at 1:31:42 PM UTC-6, Keith Thompson wrote:
>> An "object" is by definition a "region of data storage in the
>> execution environment, the contents of which can represent values".
>> (I've encouraged you several times to consult this definition.)
>> s1.x and u1.x are objects. (I'm referring to the entities that
>> "s1.x" and "u1.x" refer to, not to `s1.x` and `u2.x` as expressions;
>> as expressions, both are clearly lvalues.) Do you disagree?
>
> Given "union u { uint32_t x; float y; } u;", if both u.x and u.y are objects,
> which of the following can be said about the code "u.x = 1;":
>
> 1. The thing to the left of the equals is something other than an
> lvalue of type "uint32_t".
>
> 2. The code does not access the stored value of a "float" object.
>
> 3. The code invokes Undefined Behavior because it uses an lvalue of type
> uint32_t to access the value of a float object.
The Standard is quite clear that unions (that have more than one
member) hold multiple overlapping objects (6.2.5 p20). Here u.x
and u.y are two distinct objects, and they overlap. If you think
that doesn't make sense then you're confused about something.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-31 09:13 -0800 |
| Message-ID | <lnr33j8868.fsf@kst-u.example.com> |
| In reply to | #102846 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
[...]
> The Standard is quite clear that unions (that have more than one
> member) hold multiple overlapping objects (6.2.5 p20). Here u.x
> and u.y are two distinct objects, and they overlap. If you think
> that doesn't make sense then you're confused about something.
Agreed. 6.2.5p20 says:
A *union type* describes an overlapping nonempty set of member
objects, each of which has an optionally specified name and possibly
distinct type.
The phrase "union type" is in italics, indicating that this is the
definition of the term.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web