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 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-31 10:17 -0800 |
| Message-ID | <698d5687-fb5e-488d-841e-99991d26c314@googlegroups.com> |
| In reply to | #102846 |
On Tuesday, January 31, 2017 at 10:45:31 AM UTC-6, Tim Rentsch wrote:
> supercat writes:
> > 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.
Explain the error in my logic, given "union {int i; float f;} u; u.i=4;"
[within a function]:
1. "u.i" is an lvalue of type "int".
2. The statement "u.i=4;" writes to an lvalue of type int.
3. There exists an object, known as "u.f", whose declared type is "float".
4. The act of writing to that lvalue of type "int" also constitutes an
access to the storage underlying u.f.
5. Because u.f has a declared type of "float", its Effective Type is also
"float".
6. The Standard authorizes compilers to do anything whatsoever if the
storage of an object with one Effective Type is accessed using an
lvalue of an incompatible type, and "int" is not a type compatible
with "float".
7. The aforementioned code invokes UB.
In the absence of aliasing rules, there would be no problem with saying that
if the bit pattern stored in "u" is a valid bit pattern for an "int" and also
a valid bit pattern for a "float", the storage "represents" values of both
types simultaneously. I fail to see, however, how aliasing rules do not
cause almost all code that uses unions to invoke UB unless one of the
following is true:
1. The lvalue expression "u.i" yields something other than an lvalue of
type "int" [though I see no basis for saying that].
2. There isn't an object with effective type "float" sharing the same
storage [though you're arguing against that possibility].
3. A write to "u.i" doesn't access the storage associated with "u.f"
[which would seem implausible, since it clearly *does* access that
storage].
Which of the following applies, or is there something I'm missing?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-02-01 01:51 +0000 |
| Message-ID | <87y3xqn0fe.fsf@bsb.me.uk> |
| In reply to | #102853 |
supercat@casperkitty.com writes:
> On Tuesday, January 31, 2017 at 10:45:31 AM UTC-6, Tim Rentsch wrote:
>> supercat writes:
>> > 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.
>
> Explain the error in my logic, given "union {int i; float f;} u; u.i=4;"
> [within a function]:
>
> 1. "u.i" is an lvalue of type "int".
>
> 2. The statement "u.i=4;" writes to an lvalue of type int.
>
> 3. There exists an object, known as "u.f", whose declared type is "float".
A union holds only one object at a time.
> 4. The act of writing to that lvalue of type "int" also constitutes an
> access to the storage underlying u.f.
Since a union holds only one object at a time the update of u.i is only
to that object.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-01 14:24 -0800 |
| Message-ID | <151d7ce8-f628-4f42-a2a3-c92a8bb7e682@googlegroups.com> |
| In reply to | #102892 |
On Tuesday, January 31, 2017 at 7:51:24 PM UTC-6, Ben Bacarisse wrote: > A union holds only one object at a time. According to Tim Rentsch (Jan 31): > 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. So, do unions hold multiple overlapping objects, or do they only hold one object at a time, or does the term "object" have multiple meanings, such that a union can holds two overlapping objects (by one definition), but only holds one object (other definition) at a time?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-02-02 03:07 +0000 |
| Message-ID | <87a8a5mgte.fsf@bsb.me.uk> |
| In reply to | #102935 |
supercat@casperkitty.com writes: > On Tuesday, January 31, 2017 at 7:51:24 PM UTC-6, Ben Bacarisse wrote: >> A union holds only one object at a time. > > According to Tim Rentsch (Jan 31): >> 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. > > So, do unions hold multiple overlapping objects, or do they only hold one > object at a time, or does the term "object" have multiple meanings, such > that a union can holds two overlapping objects (by one definition), but > only holds one object (other definition) at a time? They hold one at a time. The union type defines a set of member objects, only one of which is present at any time in any instance of that type. Do you disagree? If so, why? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-02-04 04:43 -0800 |
| Message-ID | <kfn8tpm9le4.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #102944 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> supercat@casperkitty.com writes:
>
>> On Tuesday, January 31, 2017 at 7:51:24 PM UTC-6, Ben Bacarisse wrote:
>>> A union holds only one object at a time.
>>
>> According to Tim Rentsch (Jan 31):
>>
>>> 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.
>>
>> So, do unions hold multiple overlapping objects, or do they only hold one
>> object at a time, or does the term "object" have multiple meanings, such
>> that a union can holds two overlapping objects (by one definition), but
>> only holds one object (other definition) at a time?
>
> They hold one at a time. The union type defines a set of member
> objects, only one of which is present at any time in any instance of
> that type. Do you disagree? If so, why?
I guess I should jump in here. My understanding of what the
Standard says (or maybe is trying to say) is that all the member
objects are always there, but only one value can be held at a
time. The point of the footnote that says a union can contain
only one member at a time is to differentiate it from other types
where several values can be held independently. Assigning into
one member (object) doesn't make the other member (objects) go
out of existence; it does cause whatever previous value was
stored to go away, but doesn't affect whether the objects exist.
For reference here is that footnote:
Note that aggregate type does not include union type because
an object with union type can only contain one member at a
time.
The question of whether a member (object) "exists" may sound a
bit like metaphysics. I hold the view that I have (about member
or object "existence") because it seems most consistent with
other parts of the Standard. For example, besides the definition
of union types that says they have multiple overlapping objects,
there is this statement in 6.2.6.1 p7:
When a value is stored in a member of an object of union
type, the bytes of the object representation that do not
correspond to that member but do correspond to other members
take unspecified values.
Read in conjunction with 6.2.5 p20, to me this implies that
the various member objects are always all there; only one
of them holds a value at any one time, but the objects don't
go out of existence just because they don't hold a value.
Consider a local declaration like 'int i;'. The object for
'i' exists as soon as its surrounding block is entered, yet
it hasn't been given a value - indeed it may never be
given a value, but despite that the object exists. The
same holds of union member objects.
So for what it's worth there is my view and some of the
reasoning behind it.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-04 08:01 -0800 |
| Message-ID | <276589b7-b156-44a0-baeb-551aa95691a2@googlegroups.com> |
| In reply to | #103132 |
On Saturday, February 4, 2017 at 6:43:39 AM UTC-6, Tim Rentsch wrote: > The question of whether a member (object) "exists" may sound a > bit like metaphysics. I hold the view that I have (about member > or object "existence") because it seems most consistent with > other parts of the Standard. For example, besides the definition > of union types that says they have multiple overlapping objects, > there is this statement in 6.2.6.1 p7: > > When a value is stored in a member of an object of union > type, the bytes of the object representation that do not > correspond to that member but do correspond to other members > take unspecified values. > > Read in conjunction with 6.2.5 p20, to me this implies that > the various member objects are always all there; only one > of them holds a value at any one time, but the objects don't > go out of existence just because they don't hold a value. > Consider a local declaration like 'int i;'. The object for > 'i' exists as soon as its surrounding block is entered, yet > it hasn't been given a value - indeed it may never be > given a value, but despite that the object exists. The > same holds of union member objects. In the stateent "unionName.member = someValue" is there anything in the Standard that would regard the left half of the assignment as an lvalue of anything other than the member type? Is there anything that would imply that such a statement does not access the stored value of other members? I would agree with anyone who would regard it as nonsensical that an access to a union member would invoke UB unless all members of the union are alias-compatible, but unless there's something I'm missing the most logical inference from that would be that the aliasing rules, as written, are nonsensical.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-02-09 09:06 -0800 |
| Message-ID | <kfnr33747l5.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #103140 |
supercat@casperkitty.com writes: > On Saturday, February 4, 2017 at 6:43:39 AM UTC-6, Tim Rentsch wrote: >> The question of whether a member (object) "exists" may sound a >> bit like metaphysics. I hold the view that I have (about member >> or object "existence") because it seems most consistent with >> other parts of the Standard. For example, besides the definition >> of union types that says they have multiple overlapping objects, >> there is this statement in 6.2.6.1 p7: >> >> When a value is stored in a member of an object of union >> type, the bytes of the object representation that do not >> correspond to that member but do correspond to other members >> take unspecified values. >> >> Read in conjunction with 6.2.5 p20, to me this implies that >> the various member objects are always all there; only one >> of them holds a value at any one time, but the objects don't >> go out of existence just because they don't hold a value. >> Consider a local declaration like 'int i;'. The object for >> 'i' exists as soon as its surrounding block is entered, yet >> it hasn't been given a value - indeed it may never be >> given a value, but despite that the object exists. The >> same holds of union member objects. > > In the stateent "unionName.member = someValue" is there anything in the > Standard that would regard the left half of the assignment as an lvalue > of anything other than the member type? This sounds like a rhetorical question. What is your answer? Do you have any reason to think my answer is different than yours? > Is there anything that would imply that such a statement does not access > the stored value of other members? This also sounds like a rhetorical question. Do you have any opinion of your own on that question? Is there some reason you don't state it? Do you think your view on this question differs from mine? If so can you say why? > I would agree with anyone who would regard it as nonsensical that an access > to a union member would invoke UB unless all members of the union are > alias-compatible, but unless there's something I'm missing the most logical > inference from that would be that the aliasing rules, as written, are > nonsensical. That assumes that other people interpret the Standard the same way you do, which by all indications they do not.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-09 11:56 -0800 |
| Message-ID | <00c2c595-687f-4f18-a7a6-a076e8253e71@googlegroups.com> |
| In reply to | #103534 |
On Thursday, February 9, 2017 at 11:06:38 AM UTC-6, Tim Rentsch wrote:
> supercat writes:
> > In the stateent "unionName.member = someValue" is there anything in the
> > Standard that would regard the left half of the assignment as an lvalue
> > of anything other than the member type?
>
> This sounds like a rhetorical question. What is your answer?
> Do you have any reason to think my answer is different than yours?
> > Is there anything that would imply that such a statement does not access
> > the stored value of other members?
>
> This also sounds like a rhetorical question. Do you have any
> opinion of your own on that question? Is there some reason
> you don't state it? Do you think your view on this question
> differs from mine? If so can you say why?
So far as I can tell, in order for the behavior of the above to be defined
in cases where the union contains types that are not alias compatible, at
least one of the following must apply:
1. The aforementioned statement is something other than a write to an
lvalue of the member type.
2. The aforementioned statement does not access the stored value of
other objects within the union.
3. Programmers are entitled to regard behavior as defined in some cases
where common sense would suggest that it should be, even if a literal
reading of the Standard would imply that it isn't.
4. Programmers are not entitled to expect that implementations will act
in defined fashion when making any access to a union which contains
types that are not alias-compatible with the type used for access.
Nothing I've seen in the Standard would directly support any of the above
statements, but I see no way they could all be false without leading to a
contradiction. So which one is true?
> > I would agree with anyone who would regard it as nonsensical that an access
> > to a union member would invoke UB unless all members of the union are
> > alias-compatible, but unless there's something I'm missing the most logical
> > inference from that would be that the aliasing rules, as written, are
> > nonsensical.
>
> That assumes that other people interpret the Standard the same
> way you do, which by all indications they do not.
I would expect people who have considered the above statements and their
implications would regard at least one of them as true, though they may
differ as to which one.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-02-12 10:29 -0800 |
| Message-ID | <kfn7f4v2rfu.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #103559 |
supercat@casperkitty.com writes: > On Thursday, February 9, 2017 at 11:06:38 AM UTC-6, Tim Rentsch wrote: >> supercat writes: >>> In the stateent "unionName.member = someValue" is there anything in the >>> Standard that would regard the left half of the assignment as an lvalue >>> of anything other than the member type? >> >> This sounds like a rhetorical question. What is your answer? >> Do you have any reason to think my answer is different than yours? >> >>> Is there anything that would imply that such a statement does not access >>> the stored value of other members? >> >> This also sounds like a rhetorical question. Do you have any >> opinion of your own on that question? Is there some reason >> you don't state it? Do you think your view on this question >> differs from mine? If so can you say why? > > So far as I can tell, in order for the behavior of the above to be defined > in cases where the union contains types that are not alias compatible, at > least one of the following must apply: > > 1. The aforementioned statement is something other than a write to an > lvalue of the member type. > > 2. The aforementioned statement does not access the stored value of > other objects within the union. > > 3. Programmers are entitled to regard behavior as defined in some cases > where common sense would suggest that it should be, even if a literal > reading of the Standard would imply that it isn't. > > 4. Programmers are not entitled to expect that implementations will act > in defined fashion when making any access to a union which contains > types that are not alias-compatible with the type used for access. > > Nothing I've seen in the Standard would directly support any of the above > statements, but I see no way they could all be false without leading to a > contradiction. So which one is true? Your argument about two members of a union is equally applicable for a member of a struct and the struct as a whole, which is obviously a nonsensical result. Somewhere along the way your reasoning got mixed up. >>> I would agree with anyone who would regard it as nonsensical that an access >>> to a union member would invoke UB unless all members of the union are >>> alias-compatible, but unless there's something I'm missing the most logical >>> inference from that would be that the aliasing rules, as written, are >>> nonsensical. >> >> That assumes that other people interpret the Standard the same >> way you do, which by all indications they do not. > > I would expect people who have considered the above statements and their > implications would regard at least one of them as true, though they may > differ as to which one. What you mean by "a literal reading" and what someone else means by "a literal reading" might not be the same thing, did you ever think of that? Again, the problem you're having is assuming other people interpret the Standard the same way you do, which by all indications they do not.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-12 13:43 -0800 |
| Message-ID | <db48a6eb-67ad-49f2-bd5f-b2d682aa8850@googlegroups.com> |
| In reply to | #103746 |
On Sunday, February 12, 2017 at 12:29:48 PM UTC-6, Tim Rentsch wrote: > supercat writes: > > So far as I can tell, in order for the behavior of the above to be defined > > in cases where the union contains types that are not alias compatible, at > > least one of the following must apply: > > > > 1. The aforementioned statement is something other than a write to an > > lvalue of the member type. > > > > 2. The aforementioned statement does not access the stored value of > > other objects within the union. > > > > 3. Programmers are entitled to regard behavior as defined in some cases > > where common sense would suggest that it should be, even if a literal > > reading of the Standard would imply that it isn't. > > > > 4. Programmers are not entitled to expect that implementations will act > > in defined fashion when making any access to a union which contains > > types that are not alias-compatible with the type used for access. > > > > Nothing I've seen in the Standard would directly support any of the above > > statements, but I see no way they could all be false without leading to a > > contradiction. So which one is true? > > Your argument about two members of a union is equally applicable for a > member of a struct and the struct as a whole, which is obviously a > nonsensical result. Somewhere along the way your reasoning got mixed > up. At least one of the above statements has to be true. Either I'm missing something in the Standard that would make #1 or #2 true, the Standard has some gaps which must be filled in with common sense, or the Standard only requires that implementations support useful behavior with some limited kinds of unions. All of those possibilities would seem plausible, but I don't know which is true, so I'm asking--which of them is true? > > I would expect people who have considered the above statements and their > > implications would regard at least one of them as true, though they may > > differ as to which one. > > What you mean by "a literal reading" and what someone else means by "a > literal reading" might not be the same thing, did you ever think of > that? That's why I allow for the possibility that #1 or #2 might be true even though I don't see anything in the Standard that would imply either. The Standard says that accessing the stored representation of an object of one type using an lvalue of a type that isn't alias-compatible invokes UB. I'm not sure how one could read that without implying that if types P and Q are not alias compatible, one of the following must be true about every statement S in the program: 1. S does not access the stored value of a P using an lvalue of type Q. 2. S invokes Undefined Behavior. The fact that people including the authors of the Standard would unanimously agree that some construct obviously should have defined behavior does not imply that the way the Standard is written actually classifies the action likewise. > Again, the problem you're having is assuming other people interpret the > Standard the same way you do, which by all indications they do not. I'm allowing for flexibility, but so far as I can tell any useful interpretation of the Standard would require that certain constructs be treated as defined behavior even though nothing in the text of the Standard requires such treatment. I think such a view would have been considered common sense back in 1989, but over time the meaning of "common sense" seems to have changed.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-02-19 21:44 -0800 |
| Message-ID | <kfnzihhv2jq.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #103763 |
supercat@casperkitty.com writes: > On Sunday, February 12, 2017 at 12:29:48 PM UTC-6, Tim Rentsch wrote: >> supercat writes: >>> So far as I can tell, in order for the behavior of the above to be defined >>> in cases where the union contains types that are not alias compatible, at >>> least one of the following must apply: >>> >>> 1. The aforementioned statement is something other than a write to an >>> lvalue of the member type. >>> >>> 2. The aforementioned statement does not access the stored value of >>> other objects within the union. >>> >>> 3. Programmers are entitled to regard behavior as defined in some cases >>> where common sense would suggest that it should be, even if a literal >>> reading of the Standard would imply that it isn't. >>> >>> 4. Programmers are not entitled to expect that implementations will act >>> in defined fashion when making any access to a union which contains >>> types that are not alias-compatible with the type used for access. >>> >>> Nothing I've seen in the Standard would directly support any of the above >>> statements, but I see no way they could all be false without leading to a >>> contradiction. So which one is true? >> >> Your argument about two members of a union is equally applicable for a >> member of a struct and the struct as a whole, which is obviously a >> nonsensical result. Somewhere along the way your reasoning got mixed >> up. > > At least one of the above statements has to be true. [...] You need a course in logic. Your underlying assumptions are inconsistent. In an inconsistent system all statements are both true and false. Also you are mixing levels and meta-levels, eg, by talking about "programmers being entitled" to something, and trying to draw conclusions from that. This kind of reasoning also leads to an inconsistent system (formally, any logic that is sigma2 complete is inconsistent). There is no point in trying to reason within such a system - all that comes out is nonsense. Go back and try to write what you mean in simple, direct language. Avoid constructions like "Programmers are entitled...". Avoid reasoning about reasoning, which basically always leads to trouble. If the assumptions, reasons, and reasoning are written down in simple and direct language then there is a good chance what and where the problem is will jump out at you. But in its current mixed up form the possibility of any fruitful discussion is essentially hopeless.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-20 08:15 -0800 |
| Message-ID | <7cf3d284-16e8-4f6a-8f3a-b62b8fbcd9c5@googlegroups.com> |
| In reply to | #104255 |
On Sunday, February 19, 2017 at 11:45:04 PM UTC-6, Tim Rentsch wrote:
> supercat writes:
> >>> 1. The aforementioned statement is something other than a write to an
> >>> lvalue of the member type.
> >>>
> >>> 2. The aforementioned statement does not access the stored value of
> >>> other objects within the union.
> >>>
> >>> 3. Programmers are entitled to regard behavior as defined in some cases
> >>> where common sense would suggest that it should be, even if a literal
> >>> reading of the Standard would imply that it isn't.
> >>>
> >>> 4. Programmers are not entitled to expect that implementations will act
> >>> in defined fashion when making any access to a union which contains
> >>> types that are not alias-compatible with the type used for access.
> > At least one of the above statements has to be true. [...]
>
> You need a course in logic. Your underlying assumptions are
> inconsistent. In an inconsistent system all statements are both
> true and false. Also you are mixing levels and meta-levels, eg,
> by talking about "programmers being entitled" to something, and
> trying to draw conclusions from that. This kind of reasoning
> also leads to an inconsistent system (formally, any logic that is
> sigma2 complete is inconsistent). There is no point in trying to
> reason within such a system - all that comes out is nonsense.
All right--let me reword substitute the following for the last two:
3. Something in the Standard defines the behavior in the aforementioned
case, despite the fact that it violates a "shall" run-time constraint.
4. Nothing in the Standard defines the behavior in the aforementioned
case, but it's somehow possible for code which is portable and not
defective to access a member of a union whose types are not alias-
compatible [note that I'm not talking about code which writes one type
and reads another, which would be non-portable].
5. Nothing in the Standard defines the behavior in the aforementioned
case, and it is thus not possible for code which is portable and is
not defective to access a member of a union whose types are not alias-
compatible, even if code never reads the union using any type other than
the last one written.
> If the assumptions, reasons, and reasoning are written
> down in simple and direct language then there is a good chance
> what and where the problem is will jump out at you. But in its
> current mixed up form the possibility of any fruitful discussion
> is essentially hopeless.
I believe the "problem" lies with an axiomatic belief that some compiler
writers have which suggest that any code whose behavior is not defined by
the text of the Standard should be viewed as "defective" or "non-portable".
Omit that axiom, and statement #4 above would pose no problem.
In many fields, it is broadly recognized that quality systems will try to
uphold the Principle of Least Astonishment. While is sometimes difficult
to precisely define what behaviors should be viewed as "astonishing", it
is usually pretty easy to subdivide behaviors into three categories:
1. Those which would be so obviously regarded as "astonishing" that a
quality system would have the responsibility of preventing such
behaviors, and users of such a system should not need to prepare for
them.
2. Those which are so obviously "not astonishing" that quality systems
have no responsibility to prevent them, and users of such systems have
the responsibility of preparing for them.
3. Those which might be somewhat astonishing; quality systems should
generally prevent such behaviors, but users should prepare for the
possibility that the systems won't.
In general, the size of #3 will be inversely proportional to the level of
detail in the documentation, since documentation can move behaviors from
category #3 to category #1 or #2. Shrinking the size of #3 can make a
system more efficient by eliminating redundancy, but once #3 gets down to
a certain size, the cost of additional documentation to reduce it further
would exceed the cost of any redundancy thus eliminated.
If one subscribes to the POLA, it becomes important to categorize what
behaviors should be viewed as astonishing or not astonishing. Saying that
a programmer is entitled to expect X will happen is a equivalent to saying
that a failure of X to occur should be viewed as "astonishing", and as a
consequence a compiler that abides by the POLA (as quality systems generally
should) would have a responsibility to either ensure that X occurs, or else
ensure via some means (likely through documentation) that a programmer would
not be entitled to expect it to.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-02-24 07:58 -0800 |
| Message-ID | <kfnlgsvtwax.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #104269 |
supercat@casperkitty.com writes: > On Sunday, February 19, 2017 at 11:45:04 PM UTC-6, Tim Rentsch wrote: >> supercat writes: >>>>> 1. The aforementioned statement is something other than a write to an >>>>> lvalue of the member type. >>>>> >>>>> 2. The aforementioned statement does not access the stored value of >>>>> other objects within the union. >>>>> >>>>> 3. Programmers are entitled to regard behavior as defined in some cases >>>>> where common sense would suggest that it should be, even if a literal >>>>> reading of the Standard would imply that it isn't. >>>>> >>>>> 4. Programmers are not entitled to expect that implementations will act >>>>> in defined fashion when making any access to a union which contains >>>>> types that are not alias-compatible with the type used for access. >>> >>> At least one of the above statements has to be true. [...] >> >> You need a course in logic. Your underlying assumptions are >> inconsistent. In an inconsistent system all statements are both >> true and false. Also you are mixing levels and meta-levels, eg, >> by talking about "programmers being entitled" to something, and >> trying to draw conclusions from that. This kind of reasoning >> also leads to an inconsistent system (formally, any logic that is >> sigma2 complete is inconsistent). There is no point in trying to >> reason within such a system - all that comes out is nonsense. > > All right--let me reword substitute the following for the last two: > > 3. Something in the Standard defines the behavior in the aforementioned > case, despite the fact that it violates a "shall" run-time constraint. > > 4. Nothing in the Standard defines the behavior in the aforementioned > case, but it's somehow possible for code which is portable and not > defective to access a member of a union whose types are not alias- > compatible [note that I'm not talking about code which writes one type > and reads another, which would be non-portable]. > > 5. Nothing in the Standard defines the behavior in the aforementioned > case, and it is thus not possible for code which is portable and is > not defective to access a member of a union whose types are not alias- > compatible, even if code never reads the union using any type other than > the last one written. No, don't start in the middle, start over at the beginning. The original points (1) and (2) refer to "the aforementioned". There is no "aforementioned". You snipped it upthread. Avoid compound sentences. Avoid pronouns. Avoid referring to other parts of the text except by explicit labelled references. >> If the assumptions, reasons, and reasoning are written >> down in simple and direct language then there is a good chance >> what and where the problem is will jump out at you. But in its >> current mixed up form the possibility of any fruitful discussion >> is essentially hopeless. > > I believe the "problem" lies with [...] The problem you're having now is that your conclusions are not consistent with everyone else's. Until you learn to express yourself in a way that communicates effectively with other people, /and vice versa/, that problem is not going to go away. A tall order, I know, but there it is.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-24 10:00 -0800 |
| Message-ID | <d74fd7b1-1dea-443d-8617-2be77c9b51ba@googlegroups.com> |
| In reply to | #104593 |
On Friday, February 24, 2017 at 9:58:56 AM UTC-6, Tim Rentsch wrote:
> The problem you're having now is that your conclusions are not
> consistent with everyone else's. Until you learn to express
> yourself in a way that communicates effectively with other
> people, /and vice versa/, that problem is not going to go away.
> A tall order, I know, but there it is.
The following questions assume the following declaration is in scope, and
for questions about code, assume the scope is within some function and is
executed.
union { unsigned u; float f; } uf;
True or false: the Standard specifies as a runtime constraint that stored
value of an object of type "float" may not be accessed with an lvalue of
type "unsigned". Because this is a runtime constraint, the Standard
allow implementations to do anything whatsoever if code violates it. Such
permission overrides anything else in the Standard that would otherwise
define the behavior of the code.
True or false: the Standard specifies that the above declaration will, among
other things, create an object of type "float" which is stored within "uf",
and such object will exist as long as containing "uf" object exists.
True or false: the Standard specifies that the expression "uf.u" will
is an lvalue of type "unsigned".
True or false: the Standard allows an implementation to process the
statement "uf.u = 4;" in a way that writes to the stored value of the float
value stored within "uf".
True or false: the Standard allows an implementation to process the
statement "uf.u = 4;" in a way that would cause a stored value of type
"float" to be accessed using an lvalue of type "unsigned", violating a
runtime constraint.
True or false: if any of the ways in which a conforming implementation
could process an action invoke UB, the action itself invokes UB.
If all of the above are true, they would imply that given the above union,
an attempt to write member "uf.u" may be regarded as violating a runtime
constraint, and would thus invoke UB, regardless of whether code makes any
effort to use "uf.f".
The only way I can see for the Standard to impose any requirements on the
behavior of code which writes "uf.u" would be for the language of the
Standard to be interpreted in such a way that at least one of the above
true-false statements is false. I suspect that that any compiler that
applied aliasing constraints to the above code for the purpose of
disregarding everything else would be widely denounced as a piece of junk.
Since the Standard acknowledges the possibility of conforming-but-useless
implementations, however, I see no reason to believe it a compiler that
interpreted aliasing rules as described could not be conforming.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-02-24 18:58 +0000 |
| Message-ID | <kn%rA.6317$2h7.4266@fx10.iad> |
| In reply to | #104612 |
supercat@casperkitty.com writes:
>On Friday, February 24, 2017 at 9:58:56 AM UTC-6, Tim Rentsch wrote:
>> The problem you're having now is that your conclusions are not
>> consistent with everyone else's. Until you learn to express
>> yourself in a way that communicates effectively with other
>> people, /and vice versa/, that problem is not going to go away.
>> A tall order, I know, but there it is.
>
>The following questions assume the following declaration is in scope, and
>for questions about code, assume the scope is within some function and is
>executed.
>
> union { unsigned u; float f; } uf;
>
>True or false: the Standard specifies as a runtime constraint that stored
>value of an object of type "float" may not be accessed with an lvalue of
>type "unsigned". Because this is a runtime constraint, the Standard
>allow implementations to do anything whatsoever if code violates it. Such
>permission overrides anything else in the Standard that would otherwise
>define the behavior of the code.
If an implementation did _anything_ other than overlay 'u' and 'f' in the
same allocated storage, it would break forty-five years of working code.
Not gonna happen.
The fact that the standard made it UB, or added verbiage that
makes punning UB, is superceeded by backwards compatibility.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-02-24 13:03 -0800 |
| Message-ID | <e25e40df-06ca-4b93-a93c-1070c523d186@googlegroups.com> |
| In reply to | #104621 |
On Friday, February 24, 2017 at 12:58:31 PM UTC-6, Scott Lurndal wrote: > The fact that the standard made it UB, or added verbiage that > makes punning UB, is superceeded by backwards compatibility. Of course no reasonable compiler would treat such code as UB, but some people argue that any code whose behavior is not mandated by the Standard should be regarded as "non-portable" if not outright "broken", even if 100% of compilers to date have behaved consistently and a lot of code relies upon it. It shouldn't be necessary for the Standard to forbid all of the unreasonable ways in which a capricious implementation might behave, especially given that behaviors that would make a compiler totally unsuitable for one purpose might make it more suitable for another. On the flip side, however, the fact that the authors would allow a compiler behavior implies no judgment as to whether such behavior would be appropriate in a compiler aimed at any particular purpose. Any place in the Standard which mentions run-time constraints should be read as though it contains a proviso that implementations may waive the constraints in any cases where the a reasonable judgment of an implementation's intended purpose, target platform, application field, extant code base, etc. would suggest that it should be waived. That should be so obvious as to go without saying, but applying it to e.g. the C89 aliasing rules would give something much more workable than anything that's appeared since: 1. Implementations may generally assume that objects of different types won't alias *in cases where they have no reason to expect them to*, provided they document what assumptions they make. Quality implementations will make reasonable effort to identify cases where aliasing is likely, though the level of caution may vary depending upon an implementations' target platform, application field, etc. 2. Programmers should be aware that compilers may employ type-based aliasing assumptions and should ensure that compilers have reason to expect aliasing in any case the programmers are relying upon it. Compilers writers that don't use aliasing rules as an excuse *in and of themselves* not to recognize aliasing even in cases where it should be obvious could probably apply more optimizations than the C89 Standard would allow, while breaking relatively little code.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-02-24 14:11 -0800 |
| Message-ID | <ln7f4fi6i9.fsf@kst-u.example.com> |
| In reply to | #104641 |
supercat@casperkitty.com writes:
[...]
> Any place in the Standard which mentions run-time constraints
[...]
is in Annex K (or 3.18, where the term is defined, or in the index).
The phrase "runtime-constraint" does not mean what you think it means.
--
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 | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-02-24 12:42 -0800 |
| Message-ID | <lnfuj3ian8.fsf@kst-u.example.com> |
| In reply to | #104612 |
supercat@casperkitty.com writes:
> On Friday, February 24, 2017 at 9:58:56 AM UTC-6, Tim Rentsch wrote:
>> The problem you're having now is that your conclusions are not
>> consistent with everyone else's. Until you learn to express
>> yourself in a way that communicates effectively with other
>> people, /and vice versa/, that problem is not going to go away.
>> A tall order, I know, but there it is.
>
> The following questions assume the following declaration is in scope, and
> for questions about code, assume the scope is within some function and is
> executed.
>
> union { unsigned u; float f; } uf;
>
> True or false: the Standard specifies as a runtime constraint that stored
> value of an object of type "float" may not be accessed with an lvalue of
> type "unsigned". Because this is a runtime constraint, the Standard
> allow implementations to do anything whatsoever if code violates it. Such
> permission overrides anything else in the Standard that would otherwise
> define the behavior of the code.
False. The term "runtime-constraint", introduced in C11, applies only
to calls to library functions specified in the optional Annex K.
I think you meant (or should have meant) "undefined behavior".
If you'd like to try again, please cite the wording in the standard
that says the behavior is undefined (if there is such wording).
In fact, I strongly suggest you support each of your true/false
statements with a direct citation of the standard (N1570 is fine).
That will make it easier for the rest of us to follow along, and I for
one have a fairly low threshold for how much effort I'm willing to put
into this.
> True or false: the Standard specifies that the above declaration will, among
> other things, create an object of type "float" which is stored within "uf",
> and such object will exist as long as containing "uf" object exists.
There might be some question of whether the float object uf.f "exists"
when the unsigned member uf.u is the one that was most recently written.
I am not attempting here to answer any such question, just observing
that this is a point that calls for extra clarity.
> True or false: the Standard specifies that the expression "uf.u" will
> is an lvalue of type "unsigned".
I presume you meant "is" rather than "will is". I agree that the
statement is true, but I'm being cautious because you've misused the
term "lvalue" before.
> True or false: the Standard allows an implementation to process the
> statement "uf.u = 4;" in a way that writes to the stored value of the float
> value stored within "uf".
I suggest wording this more clearly. One can write to an object, not to
a value; writing to an object updates the value that's stored in that
object.
> True or false: the Standard allows an implementation to process the
> statement "uf.u = 4;" in a way that would cause a stored value of type
> "float" to be accessed using an lvalue of type "unsigned", violating a
> runtime constraint.
Again, you're misusing the term "runtime constraint".
> True or false: if any of the ways in which a conforming implementation
> could process an action invoke UB, the action itself invokes UB.
I think there's a statement in the standard that's similar to that,
though I'm not at all certain about it. If there is, I suggest citing
it directly so we can judge whether your summary is accurate.
[snip]
It's quite possible that the standard's wording on union members is
internally inconsistent (that "quite possible" is mostly reflective of
my current state of ignorance on the matter). One particular question
I'm curious about is whether the footnote in 6.5.2.3:
If the member used to read the contents of a union object is
not the same as the member last used to store a value in the
object, the appropriate part of the object representation of
the value is reinterpreted as an object representation in the
new type as described in 6.2.6 (a process sometimes called
"type punning). This might be a trap representation.
can be inferred from the normative wording of the standard.
(It clearly represents the intent of the committee. The question
is whether that intent is sufficiently clearly stated in normative
text.)
--
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 | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-02-24 13:49 -0800 |
| Message-ID | <lnbmtri7ii.fsf@kst-u.example.com> |
| In reply to | #104639 |
Keith Thompson <kst-u@mib.org> writes:
> supercat@casperkitty.com writes:
[...]
>> True or false: if any of the ways in which a conforming implementation
>> could process an action invoke UB, the action itself invokes UB.
>
> I think there's a statement in the standard that's similar to that,
> though I'm not at all certain about it. If there is, I suggest citing
> it directly so we can judge whether your summary is accurate.
The statement I was thinking of is in N1570 6.5p2:
If there are multiple allowable orderings of the subexpressions
of an expression, the behavior is undefined if such an
unsequenced side effect occurs in any of the orderings.
I don't believe it applies to the union member access you're talking
about. Perhaps you were thinking of some other wording in the standard.
--
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-02-24 13:58 -0800 |
| Message-ID | <6c8379ea-4a8a-4d88-9c3c-0c9e6d5aff04@googlegroups.com> |
| In reply to | #104639 |
On Friday, February 24, 2017 at 2:42:07 PM UTC-6, Keith Thompson wrote: > supercat writes: > > True or false: the Standard specifies as a runtime constraint that stored > > value of an object of type "float" may not be accessed with an lvalue of > > type "unsigned". Because this is a runtime constraint, the Standard > > allow implementations to do anything whatsoever if code violates it. Such > > permission overrides anything else in the Standard that would otherwise > > define the behavior of the code. > > False. The term "runtime-constraint", introduced in C11, applies only > to calls to library functions specified in the optional Annex K. I believe that if the structure of a program violates a "shall" clause in the Standard in such a way as to require a diagnostic, such violation is referred to as a constraint violation. That would suggest that at least as far as ordinary English construction is concerned, a "shall" clause which is only applicable to run-time behavior would be a run-time constraint, though I see that a similar phrase with different hyphenation has been given another meaning. Since the phrase "a 'shall' or 'shall not' requirement that appears outside of a constraint or runtime-constraint" is a bit unwieldy, perhaps you can suggest something more to your liking? > I think you meant (or should have meant) "undefined behavior". > If you'd like to try again, please cite the wording in the standard > that says the behavior is undefined (if there is such wording). > In fact, I strongly suggest you support each of your true/false > statements with a direct citation of the standard (N1570 is fine). > That will make it easier for the rest of us to follow along, and I for > one have a fairly low threshold for how much effort I'm willing to put > into this. N1570 6.5 [Expressions] p7. An object SHALL have its stored value accessed only by an lvalue expression which has one of the following types: ... None of the listed cases would be applicable in the scenario of an object of type "float" having its stored value accessed by an lvalue of type "unsigned". Most forms of Undefined Behavior are undefined by omission. By contrast, code which violates "a 'shall' or 'shall not' requirement that appears outside of a constraint or runtime-constraint" invokes UB even if behavior would be defined in the absence of that requirement. > > True or false: the Standard specifies that the above declaration will, among > > other things, create an object of type "float" which is stored within "uf", > > and such object will exist as long as containing "uf" object exists. > > There might be some question of whether the float object uf.f "exists" > when the unsigned member uf.u is the one that was most recently written. > I am not attempting here to answer any such question, just observing > that this is a point that calls for extra clarity. It has been claimed that all union member objects exist for the lifetime of the union. If for purposes of that rule only active union members "exist", that would resolve the issue, but I don't see anything in the Standard that describes how union member objects are created and destroyed separate from the union itself. > > True or false: the Standard specifies that the expression "uf.u" will > > is an lvalue of type "unsigned". > > I presume you meant "is" rather than "will is". I agree that the > statement is true, but I'm being cautious because you've misused the > term "lvalue" before. > > True or false: the Standard allows an implementation to process the > > statement "uf.u = 4;" in a way that writes to the stored value of the float > > value stored within "uf". > > I suggest wording this more clearly. One can write to an object, not to > a value; writing to an object updates the value that's stored in that > object. The Standard uses the phrase "have its stored value accessed" in 6.5p7; but I don't see any definition for "stored value". An action that modifies something, however, would appear to be a write and consequently an "access". > > True or false: the Standard allows an implementation to process the > > statement "uf.u = 4;" in a way that would cause a stored value of type > > "float" to be accessed using an lvalue of type "unsigned", violating a > > runtime constraint. > > Again, you're misusing the term "runtime constraint". What short phrase would you suggest for "a 'shall' or 'shall not' requirement that appears outside of a constraint or runtime-constraint"? > > True or false: if any of the ways in which a conforming implementation > > could process an action invoke UB, the action itself invokes UB. > > I think there's a statement in the standard that's similar to that, > though I'm not at all certain about it. If there is, I suggest citing > it directly so we can judge whether your summary is accurate. The above is perhaps a bit over-simplistic with regard to certain Implementation-Defined behaviors, but should suffice for the cases that are relevant here. If there would be wiggle room for a compiler to regard an access to "uf.u" as either accessing or not accessing the stored value of "uf.f", the fact that a compiler wasn't required to access the stored value of a float wouldn't be sufficient to prevent UB. Only if the rules were defined such that a compiler *couldn't* regard the write to "uf.u" as accessing the stored value of a "float" would behavior be defined. > It's quite possible that the standard's wording on union members is > internally inconsistent (that "quite possible" is mostly reflective of > my current state of ignorance on the matter). One particular question > I'm curious about is whether the footnote in 6.5.2.3: > > If the member used to read the contents of a union object is > not the same as the member last used to store a value in the > object, the appropriate part of the object representation of > the value is reinterpreted as an object representation in the > new type as described in 6.2.6 (a process sometimes called > "type punning). This might be a trap representation. > > can be inferred from the normative wording of the standard. > (It clearly represents the intent of the committee. The question > is whether that intent is sufficiently clearly stated in normative > text.) If code violates a "shall" requirement that is only applicable at runtime, it invokes UB regardless of whether behavior would be defined in the absence of that requirement. If one part of the Standard would appear to define the behavior of certain actions, but most such actions would violate a "shall" requirement given in another part, the Standard's rules of construction would imply that the former is only applicable to those actions that comply with the latter requirement.
[toc] | [prev] | [next] | [standalone]
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web