Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #101118 > unrolled thread

Re: lvalues from the ternary op

Started byManfred <noname@invalid.add>
First post2017-01-04 19:46 +0100
Last post2017-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.


Contents

  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 →


#102853

Fromsupercat@casperkitty.com
Date2017-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]


#102892

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#102935

Fromsupercat@casperkitty.com
Date2017-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]


#102944

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#103132

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#103140

Fromsupercat@casperkitty.com
Date2017-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]


#103534

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#103559

Fromsupercat@casperkitty.com
Date2017-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]


#103746

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#103763

Fromsupercat@casperkitty.com
Date2017-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]


#104255

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#104269

Fromsupercat@casperkitty.com
Date2017-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]


#104593

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#104612

Fromsupercat@casperkitty.com
Date2017-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]


#104621

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-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]


#104641

Fromsupercat@casperkitty.com
Date2017-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]


#104653

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#104639

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#104649

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#104650

Fromsupercat@casperkitty.com
Date2017-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