Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #127213 > unrolled thread
| Started by | supercat@casperkitty.com |
|---|---|
| First post | 2018-03-01 16:38 -0800 |
| Last post | 2018-03-26 23:04 -0700 |
| Articles | 20 on this page of 150 — 11 participants |
Back to article view | Back to comp.lang.c
lvalue types supercat@casperkitty.com - 2018-03-01 16:38 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 17:17 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-01 17:37 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 22:00 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 23:49 -0800
Re: lvalue types asetofsymbols@gmail.com - 2018-03-05 06:56 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 00:22 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 01:23 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 05:04 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 06:06 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 08:12 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 09:50 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 11:33 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 11:45 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 16:28 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 16:54 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 17:50 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 19:43 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-02 22:51 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 23:07 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 01:44 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-03 13:01 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 22:21 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 09:24 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-03 00:58 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 01:13 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-03 13:01 -0800
Re: lvalue types supercat <flatfinger@casperkitty.com> - 2018-03-03 17:43 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-04 02:22 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-04 13:03 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-04 13:03 -0800
Re: lvalue types bartc <bc@freeuk.com> - 2018-03-04 22:32 +0000
Re: lvalue types supercat@casperkitty.com - 2018-03-05 09:45 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-19 09:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-19 11:52 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-26 23:44 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-27 09:14 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-27 12:21 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-28 17:01 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-29 01:54 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-30 08:32 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-30 09:25 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-03-30 10:58 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-31 00:52 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-02 15:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-03 10:06 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-03 11:33 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-03 12:19 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-03 12:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-05 10:17 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-05 10:52 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-05 12:39 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-06 06:13 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-04 16:38 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-27 12:09 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-28 10:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-19 12:27 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-03 14:02 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-04 17:32 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-04 20:24 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-09 08:31 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-11 11:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-11 12:44 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-12 06:45 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-12 07:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-12 14:26 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-12 14:43 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-12 17:40 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-13 03:02 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-13 00:27 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-13 07:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 08:52 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-16 10:28 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 13:58 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-16 14:52 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 16:22 -0700
Re: lvalue types Richard Damon <Richard@Damon-Family.org> - 2018-04-16 21:51 -0400
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-16 19:42 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-16 21:30 -0700
Re: lvalue types Richard Damon <Richard@Damon-Family.org> - 2018-04-17 07:01 -0400
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-17 04:22 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-19 02:43 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 07:25 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 08:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 09:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 10:37 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 11:00 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 11:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 12:45 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-17 19:55 +0000
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 13:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 14:00 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 19:45 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 08:27 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 09:12 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 10:13 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 11:01 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 11:51 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 12:15 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 12:30 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 13:25 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 10:51 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 12:38 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 14:39 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 21:17 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-19 02:40 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-19 03:01 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 06:49 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-19 07:58 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-20 08:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 12:17 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 12:51 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 13:37 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-19 21:08 +0000
Re: lvalue types supercat@casperkitty.com - 2018-04-19 14:50 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 14:56 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 16:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-21 10:27 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-23 11:37 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-18 16:07 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 09:20 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 11:25 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 14:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 15:05 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 19:57 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 08:43 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 09:36 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-17 11:37 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 20:23 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 09:23 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-18 17:29 +0000
Re: lvalue types supercat@casperkitty.com - 2018-04-18 10:47 -0700
Re: lvalue types bartc <bc@freeuk.com> - 2018-04-18 20:04 +0100
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 10:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 13:23 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 14:26 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 15:36 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 10:39 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 12:42 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-16 21:29 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-23 11:39 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-06-14 02:53 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-04 21:30 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-03 14:19 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 18:03 -0800
Re: lvalue types John Bode <jfbode1029@gmail.com> - 2018-03-21 10:33 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-21 11:53 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-22 00:11 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-21 11:53 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-26 23:04 -0700
Page 7 of 8 — ← Prev page 1 2 3 4 5 6 [7] 8 Next page →
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-18 09:20 -0700 |
| Message-ID | <33def90a-d3f0-4ac3-ac6d-8f836a7d1395@googlegroups.com> |
| In reply to | #129405 |
On Wednesday, April 18, 2018 at 11:28:07 AM UTC-4, supe...@casperkitty.com wrote: > On Tuesday, April 17, 2018 at 9:45:47 PM UTC-5, james...@verizon.net wrote: > > Taking 6.5p7 as actually written, ignoring the fact that it's clearly > > inconsistent with anything the committee could reasonably have intend to > > say, then direct use of a member of a struct is just as much undefined > > behavior as dereferencing apointer to that member. That's because 6.5p7 > > is worded solely in terms of lvalues, and dereferencing a pointer to a > > member or referring directly to a member of a struct are two equally > > valid ways of creating lvalues that refer to the member. Therefore, I > > don't see how the distinction you're making between dereferencing a > > pointer and direct use of a member is relevant to this issue. > > The ability to pass the address of an object to functions that can use > the object, at least until the next time the object is addressed via other > means, is no less fundamental than the ability to use the structure > directly. Both clang and gcc, however, *invent* a distinction between > direct and indirect use of objects. Please explain, preferably by the use of actual code where that distinction causes a difference in the actual output from the program. > [from above] > >> 1. Recognize that taking the address of a member of a struct or union object > >> yields a pointer that may be used to access the storage associated with > >> that member, at least while all operations related to that storage are > >> done exclusively with that pointer or others derived from it. > > >> 2. Recognize that applying the address-of operator of a member of a struct > >> or union object and dereferencing it--even immediately--need not have any > >> relationship to the act of using the member directly. > >> > >> 3. Treat the use of a pointer to a member as being equivalent to direct > >> use of the member, without bothering to define either. > > > > To the best of my understanding, I would expect essentially all of the > > committee members to see nothing objectionable with #1, and nothing > > worthwhile about #2 or #3. What, if anything, has given you the belief > > that there is any significant number of people on the committee who > > disagree with #1, or who agree with #2 or #3? > > Both gcc and clang are heavily invested in a design that can't reliably > handle #1. I don't think any of the Committee members would have opposed > codifying #1 back in 1989, but I think the maintainers of gcc and clang > have enough clout to block it today. I have no idea what you're talking about, and the further discussion that you provided (which I've snipped) did nothing to clarify the issue. Can you provide code that gcc handles in a way that can only be justified by misinterpreting the standard's defective wording of 6.5p7 as representing the committee's actual intent? Warning: I consider it likely that, whatever feature of gcc it is that you are talking about, it is a feature justified by aspects of 6.5p7 that I do NOT consider defective, because I think they correctly describe the intent of the committee.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 11:25 -0700 |
| Message-ID | <f8c05003-07b9-44e4-bd00-96fd1aa292ad@googlegroups.com> |
| In reply to | #129410 |
On Wednesday, April 18, 2018 at 11:21:05 AM UTC-5, james...@verizon.net wrote:
> > The ability to pass the address of an object to functions that can use
> > the object, at least until the next time the object is addressed via other
> > means, is no less fundamental than the ability to use the structure
> > directly. Both clang and gcc, however, *invent* a distinction between
> > direct and indirect use of objects.
I've posted an example above.
By my understanding of how clang and gcc work internally, code gets
converted to a form where pointers are untyped, but operations on
pointers specify the type of objects to be read or written.
Something like:
foo->bar = 3;
gets processed as "store 3 into field 'bar' of an object of [foo's type]
at address foo".
On the other hand, an expression like "&foo->bar" essentially gets
treated as a numerical computation that adds the offset of "bar" to
"foo", but doesn't actually involve any objects of "foo"'s type. This
approach can *almost* work without making note of the types of objects
involved when addresses are computed, and the authors of gcc and clang
have invested a lot of effort into getting it as close as possible to
actually working. What's unfortunate is that the amount of effort
invested trying handle all weird corner cases that arise under that model
vastly exceeds the amount of effort that would have been necessary to
simply recognize that within a context where the address of foo->bar is
taken, subsequent operations on the resulting pointer may interact with
operations on foo that occurred before the address was taken, and within
the context where the address is taken, a subsequent action on foo may
interact with operations on that pointer.
> I have no idea what you're talking about, and the further discussion
> that you provided (which I've snipped) did nothing to clarify the issue.
> Can you provide code that gcc handles in a way that can only be
> justified by misinterpreting the standard's defective wording of 6.5p7
> as representing the committee's actual intent?
I've posted a code example. I don't think anyone on the Committee would
have intended that compilers generate code that fails if uArr[i] and
uArr[j] identify the same object, but both clang and gcc do.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-04-17 14:13 -0700 |
| Message-ID | <lnin8pleo3.fsf@kst-u.example.com> |
| In reply to | #129359 |
supercat@casperkitty.com writes:
> On Tuesday, April 17, 2018 at 1:48:34 PM UTC-5, Keith Thompson wrote:
>> supercat@casperkitty.com writes:
>> > On Tuesday, April 17, 2018 at 12:37:34 PM UTC-5, Keith Thompson wrote:
>> >> Or you could just say that the standard as currently written says
>> >> the behavior is undefined (because it violates a "shall" outside
>> >> a constraint), and save us all a lot of time.
>> >>
>> >> I fail to see the point of going off on a tangent about categories of
>> >> "portable" programs.
>> >
>> > Many people claim there's no particular need to have the Standard define
>> > certain things because implementations can do so whether or not the
>> > Standard does. If the Standard is supposed to facilitate the writing of
>> > portable programs, having the standard needlessly characterize common
>> > constructs as "non-portable" undercuts that goal.
>>
>> That's not what we're talking about here.
>>
>> Nobody is saying that there's no need for the standard to define the
>> behavior of `obj.m = 42;`. Either the standard *unintentionally* fails
>> to define the behavior and that's a flaw that needs to be corrected, or
>> the standard does define it.
>>
>> "It's ok not to define the behavior of `obj.m = 42;`" is not
>> something that anyone has claimed explicitly or implicitly.
>>
>> If that's the claim you're arguing against, you win.
>
> It was apparent even in 1992 that the Standard failed to adequately specify
> the cases where a union object may be accessed using a pointer to a member.
> Had it done so, the answer to DR028 would have been obvious.
>
> Between 1992 and 1999, the lack of clarity might have been reasonably
> regarded as an oversight. Do you think the failure to address the issue
> in not just one but two subsequent revisions of the Standard continues to
> be a result of mere oversight?
Yes, I do.
It took three tries for the standard to come up with a consistent
definition of "lvalue" (compare the definitions in C90, C99,
and C11), and the standard still doesn't tell us what the value
of a string literal is or state that a parenthesized null pointer
constant is a null pointer constant. Yes, I can believe that this
is a mere oversight. (And we're talking about accessing a member
of a structure, not of a union.)
I don't say this to criticize the members of the committee.
Defining a language in an English document is hard, and a few
glitches are inevitable.
Now, without answering with more questions, can you tell us what
*you* think? Do you believe that the intended behavior of
`obj.m = 42;` (where obj is a struct object and m is a member of
type int) is anything other than obvious? If you agree with me
that the standard currently fails to define that behavior, do you
believe that to be deliberate? If so, why do you believe that,
and why would they do it?
--
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 | 2018-04-17 15:05 -0700 |
| Message-ID | <7e7487e1-342f-44f5-a094-b3b934c582b8@googlegroups.com> |
| In reply to | #129364 |
On Tuesday, April 17, 2018 at 4:13:45 PM UTC-5, Keith Thompson wrote: > Now, without answering with more questions, can you tell us what > *you* think? Do you believe that the intended behavior of > `obj.m = 42;` (where obj is a struct object and m is a member of > type int) is anything other than obvious? If you agree with me > that the standard currently fails to define that behavior, do you > believe that to be deliberate? If so, why do you believe that, > and why would they do it? I believe that the Committee thought it better to muddle along with the Status quo, where it's obvious that usable compilers must process in predictable fashion at least some things the Standard leaves undefined, but it's unclear which things must be processed predictably, than it would be to adopt any particular rule as to which things are defined and which things aren't. If you want to suggest that the Committee has no such motive, but is simply incapable of writing a decent spec, I guess I won't disagree with you, but I'd question why anyone should pay any attention to what the Committee writes, rather than what behaviors would best serve implemen- tations' users. BTW, writing a spec wouldn't be nearly so hard if the Committee were to to recognize that evaluation of an expression where an lvalue appears on the left half of an assignment operator or to the right of the address-of operator, does not *evaluate* that lvalue in question but does something significant with it [I would prefer the term "resolve"] which then produces something [I'd suggest "lref"] that is in turn used by the assignment or address-of operator. Sensible treatment of member- access operators requires having a concept of one lref being derived from another, but such a concept doesn't work with lvalues [since those are source-code expressions].
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-17 19:57 -0700 |
| Message-ID | <15a5d0f0-a310-4706-a181-3eaae0ef702a@googlegroups.com> |
| In reply to | #129368 |
On Tuesday, April 17, 2018 at 6:06:09 PM UTC-4, supe...@casperkitty.com wrote: > On Tuesday, April 17, 2018 at 4:13:45 PM UTC-5, Keith Thompson wrote: > > Now, without answering with more questions, can you tell us what > > *you* think? Do you believe that the intended behavior of > > `obj.m = 42;` (where obj is a struct object and m is a member of > > type int) is anything other than obvious? If you agree with me > > that the standard currently fails to define that behavior, do you > > believe that to be deliberate? If so, why do you believe that, > > and why would they do it? > > I believe that the Committee thought it better to muddle along with > the Status quo, where it's obvious that usable compilers must process > in predictable fashion at least some things the Standard leaves > undefined, The committee never bought into your concept of requirements that can be relied upon to be conformed with, despite never having actually been officially approved of as requirements. Access to the members of structures is too fundamentally important to C to deliberately leave it up to individual implementations to decide what to do. The defective wording was clearly unintentional. > ... but it's unclear which things must be processed predictably, > than it would be to adopt any particular rule as to which things are > defined and which things aren't. > > If you want to suggest that the Committee has no such motive, but is > simply incapable of writing a decent spec, ... I think they're perfectly capable of writing a decent spec. However, being human, and in particular, being a committee, they're also capable of writing a poorly worded specification, and have frequently done so. > ... I guess I won't disagree with > you, but I'd question why anyone should pay any attention to what the > Committee writes, rather than what behaviors would best serve implemen- > tations' users. Because the standard represents the closest thing there is to an official expert consensus on what would best serve users of C implementations. You hallucinate more consensus than actually exists, so I wouldn't expect you to be swayed by that argument, but it is in fact the key reason people pay attention to the ISO standard.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 08:43 -0700 |
| Message-ID | <3b6afacd-73ea-48a3-8038-3a4e1412fb12@googlegroups.com> |
| In reply to | #129376 |
On Tuesday, April 17, 2018 at 9:58:07 PM UTC-5, james...@verizon.net wrote:
> The committee never bought into your concept of requirements that can be
> relied upon to be conformed with, despite never having actually been
> officially approved of as requirements. Access to the members of
> structures is too fundamentally important to C to deliberately leave it
> up to individual implementations to decide what to do. The defective
> wording was clearly unintentional.
Does the Standard require that any implementation be capable of handling
more than two levels of function-call nesting? Should programmers for a
"normal" platform be entitled to expect that code which nests functions
three deep, and doesn't use very many automatic objects in any of them,
should work without bombing the stack?
While I doubt the authors of the Standard intended to leave the behavior
of aggregate-member access undefined, I think they would have regarded such
access as sufficiently fundamental that any remotely-sane compiler writer
would process such a thing correctly, whether required to or not. I also
think would have regarded something like:
actOnThing(&myUnion.member);
[in cases where the function accesses the member exclusively through the
pointer] the same way. If they did regard the second the same way, however,
their expectations with regard to sane compiler writers were misplaced.
> > If you want to suggest that the Committee has no such motive, but is
> > simply incapable of writing a decent spec, ...
>
> I think they're perfectly capable of writing a decent spec. However,
> being human, and in particular, being a committee, they're also capable
> of writing a poorly worded specification, and have frequently done so.
The C language was thriving before the ratification of the C89 Standard.
The only reason the language was ever usable, given the quality of writing
in the Standard, was that compiler writers didn't have to rely upon the
Standard to describe everything that was already well established and
non-controversial.
> > ... I guess I won't disagree with
> > you, but I'd question why anyone should pay any attention to what the
> > Committee writes, rather than what behaviors would best serve implemen-
> > tations' users.
>
> Because the standard represents the closest thing there is to an
> official expert consensus on what would best serve users of C
> implementations. You hallucinate more consensus than actually exists, so
> I wouldn't expect you to be swayed by that argument, but it is in fact
> the key reason people pay attention to the ISO standard.
In cases where the Standard defines a behavior, such behavior generally
either matches the consensus behavior that existed previously, or could
be practically added to existing implementations without difficulty (and
without breaking existing code for those implementations).
The problem is that in some cases the failure of the Standard to define a
behavior is interpreted by compiler writers as implying a consensus that
such a behavior should be viewed as unnecessary in all application fields.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-18 09:36 -0700 |
| Message-ID | <459bb3b2-0a76-4200-b234-5d7aff4c7465@googlegroups.com> |
| In reply to | #129407 |
On Wednesday, April 18, 2018 at 11:44:15 AM UTC-4, supe...@casperkitty.com wrote: > On Tuesday, April 17, 2018 at 9:58:07 PM UTC-5, james...@verizon.net wrote: > > The committee never bought into your concept of requirements that can be > > relied upon to be conformed with, despite never having actually been > > officially approved of as requirements. Access to the members of > > structures is too fundamentally important to C to deliberately leave it > > up to individual implementations to decide what to do. The defective > > wording was clearly unintentional. > > Does the Standard require that any implementation be capable of handling > more than two levels of function-call nesting? No. > ... Should programmers for a > "normal" platform be entitled to expect that code which nests functions > three deep, and doesn't use very many automatic objects in any of them, > should work without bombing the stack? Yes, but only as a matter of QoI. They can't justify calling the implementation non-conforming for that reason. There might even be severely limited platforms where that would be a reasonable limitation for an implementation of C to have. > While I doubt the authors of the Standard intended to leave the behavior > of aggregate-member access undefined, I think they would have regarded such > access as sufficiently fundamental that any remotely-sane compiler writer > would process such a thing correctly, whether required to or not. Perhaps, but I see no evidence to suggest that they intended to rely upon that. Failing to write 6.5p7 to allow such use has every appearance of having been an oversight, not something the committee did intentionally. > I also > think would have regarded something like: > > actOnThing(&myUnion.member); > > [in cases where the function accesses the member exclusively through the > pointer] the same way. If they did regard the second the same way, however, > their expectations with regard to sane compiler writers were misplaced. How have sane compiler writers mishandled this? Please provide exact code that compiles and executes in the manner you consider inappropriate, and identifier which compiler (including compiler command line options) you used to demonstrate this fact. > > > If you want to suggest that the Committee has no such motive, but is > > > simply incapable of writing a decent spec, ... > > > > I think they're perfectly capable of writing a decent spec. However, > > being human, and in particular, being a committee, they're also capable > > of writing a poorly worded specification, and have frequently done so. > > The C language was thriving before the ratification of the C89 Standard. > The only reason the language was ever usable, given the quality of writing > in the Standard, was that compiler writers didn't have to rely upon the > Standard to describe everything that was already well established and > non-controversial. The standard was deliberately written to give implementations a lot of freedom, with the expectation that they would actually use it - so even well-established and non-controversial things cannot be counted on, if the implementors have conceived a reason for not doing things that way. It's possible to use this freedom to create a useless implementation, but the fact that an implementor decided to violate well-established and non-controversial conventions is not an example of that.
[toc] | [prev] | [next] | [standalone]
| From | Steven Petruzzellis <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-04-17 11:37 -0700 |
| Message-ID | <976f4b5c-3c6d-4fce-9692-b7467ea54359@googlegroups.com> |
| In reply to | #129354 |
On Tuesday, April 17, 2018 at 10:37:34 AM UTC-7, Keith Thompson wrote:
> supercat@casperkitty.com writes:
> > On Tuesday, April 17, 2018 at 10:48:35 AM UTC-5, Keith Thompson wrote:
> >> supercat@casperkitty.com writes:
> >> > The paragraph, as written, makes any program that uses structures containing
> >> > non-character members and doesn't jump through absurd hoops to do is not
> >> > strictly conforming, even if it would otherwise (in the absence of that
> >> > paragraph) be strictly conforming and there would be no ambiguity as to its
> >> > meaning.
> >>
> >> Strict conformance is not the point. The point is that, as written
> >> (assuming my reading of the literal wording is correct), it causes
> >> such programs to have undefined behavior, a much stronger statement.
> >>
> >> This:
> >> printf("%zu\n", sizeof (int));
> >> cannot appear in a strictly conforming program, but its behavior is well
> >> defined (and its output implementation-defined).
> >
> > The Standard does not define any category of "portable" programs that are
> > not Strictly Conforming. On the other hand, since it does explicitly
> > say that any code which invokes UB is either non-portable or erroneous,
> > perhaps my objection should be that the Standard says that code which tries
> > to use non-character members of structs or unions in what should be the
> > obvious logical fashion is either non-portable or erroneous, and the fact
> > that implementations happen to behave sensibly even though they are not
> > required to do so doesn't change that.
>
> Or you could just say that the standard as currently written says
> the behavior is undefined (because it violates a "shall" outside
> a constraint), and save us all a lot of time.
>
> I fail to see the point of going off on a tangent about categories of
> "portable" programs.
>
> --
> 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"
He would have to be afflicted with dementia to be unsure of if he "never had" developed a program. When Staci Elliot can't remember his past claims and utilizes make-believe, self-esteem protecting bunk later, it's mighty apparent what his error is.
Can you get Bit Twister to agree?
Staci Elliot is trying to project their MO onto Bit Twister. For years Staci Elliot has pushed the claim that Bit Twister needs 'backing' to point out all his slander. The fact is that nobody needs any support to do that. So Staci Elliot pulls this ridiculous circus poppycock in an incompetent effort to 'hawk' the idea that Bit Twister is like he is. Don't look now, but I think Staci Elliot has a serious brocrush on Bit Twister.
--
E-commerce Simplified
https://prescottareapsychopaths.wordpress.com/shawn-ulman-psychopath
Jonas Eklundh Communication AB
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-17 20:23 -0700 |
| Message-ID | <dc671782-de34-47be-bfbc-b2c1c576d03c@googlegroups.com> |
| In reply to | #129294 |
On Monday, April 16, 2018 at 7:22:34 PM UTC-4, supe...@casperkitty.com wrote: > On Monday, April 16, 2018 at 4:53:09 PM UTC-5, james...@verizon.net wrote: > > On Monday, April 16, 2018 at 4:58:39 PM UTC-4, supe...@casperkitty.com wrote: > > > Labeling constructs as Undefined Behavior means that they are unusable in > > > Strictly Conforming programs, > > > > Yes, and not all C code needs to be strictly conforming. In fact, most > > C code fails to be strictly conforming, and this is not considered a > > problem by the committee. > > The problem is that the Standard doesn't offer any other concept of what > it would mean for a program to be written in "standard" C. Does it need to? Why? It tells you how to determine what a conforming implementation of C is or is not required to do when attempting to translate any given program. Why do you need to label some programs as "standard" C code, and others as not being standard? > > > ... and consequently reduces the range of tasks > > > that can be performed cleanly and efficiently with such programs. Since > > > > Not really - the things that are labelled "undefined behavior" are > > generally things for which no standard-defined behavior would be cleanly > > and efficiently implementable on all platforms. By allowing > > implementations to provide their own definitions, code can be written in > > C which is clean and efficient for one platform, despite the fact that > > it won't work on another platform. > > That is *generally* true, but there are some notable exceptions such as > 6.5p7. That paragraph primarily affects programs whose meaning would > otherwise be unambiguously implied by implementations' specified storage > formats. No, it does not imply it. Just because data is stored in a given format does not guarantee that any particular piece of syntax is a safe way to retrieve that data. 6.5p7 is intended to tell you something about the safe ways of retrieving it, and in doing so, fails to correctly reflect what I believe to be the intent of the committee - at least, if it does reflect their intent, they need psychiatric evaluation. ... > > No - as I indicated farther up-thread, it is my contention that this > > part of the wording of the standard is defective by reason of not > > clearly conveying the intentions of the committee. Is that really so > > hard to believe? Any document of any significant size contains such > > defects. > > How often do such defects persist through decades of revisions? More frequently than we'd like. For instance, the definition of an expression (6.5p1) has undergone several revisions, and still remains inconsistent with normal use and the grammar production "expression" (6.5.17p1) (which is probably what it was intended to describe). ... > > > Let me rephrase it: how should one distinguish between cases where the > > > Standard says a construct is undefined, but that's sufficiently obviously > > > a mistake that programmers should feel safe using it anyway, from those > > > which programmers must avoid because compiler writers will interpret them > > > as "optimization" opportunities. > > > > That requires a fair amount of awareness of and sympathy with the goals > > of the committee, something that I doubt you'll ever have, since your > > goals are so different. > > What are the goals of the Committee? Does it actually have a coherent > goal, or do different members have different contradictory goals that > prevent the formation of a coherent one? It's a committee - of course it has multiple contradictory goals. However, there is a statement of the general goals that the committee has agreed to, and that statement is fairly coherent, and it falls far short of making consistency with existing implementations of C the absolute top priority that you claim it is. > > To me, it seems patently obvious that the current wording gives > > undefined behavior to such accesses, and that it would be ridiculous for > > that to be the case. I believe that it was intended that a structure's > > value be modifiable by (recursively) the use of an lvalue that has the > > type of one of the struct's members, and which refers to a member of the > > structure of that type, but only so long as the modification to the > > struct's value are restricted to a corresponding change of that member's > > value. > > What is the intended purpose of having the address-of operator yield a > pointer of an aggregate's member type when applied to an lvalue of the > form aggregate.member or aggregatePtr->member? Is it to yield a pointer > that may be used to access an object of that type in at least some > circumstances? If so, in what circumstances? It's intended to be usable for that purpose anytime that no other aspect of the program gives such code undefined behavior (as would be the case if, for instance, the containing object's lifetime had expired, so the pointer was no longer valid). Why do you ask? Dereferencing a pointer to a member is just as valid a way to create an lvalue referring to that member as using the member selection operator. And both approaches have undefined behavior according to 6.5p7 in most circumstances, which could not possibly have been the intent of sane committee members.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 09:23 -0700 |
| Message-ID | <df41050d-34cc-451b-bc68-59231996e6e5@googlegroups.com> |
| In reply to | #129377 |
On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5, james...@verizon.net wrote:
> On Monday, April 16, 2018 at 7:22:34 PM UTC-4, supe...@casperkitty.com wrote:
> > The problem is that the Standard doesn't offer any other concept of what
> > it would mean for a program to be written in "standard" C.
>
> Does it need to? Why? It tells you how to determine what a conforming implementation of C is or is not required to do when attempting to translate any given program. Why do you need to label some programs as "standard" C code, and others as not being standard?
I would suggest that a major purpose of the Standard should be to make it
possible for compiler writers to produce implementations that may be safely
fed as wide a variety of programs as practical, and for programmers to
write programs that may be safely fed to as wide a variety of implementations
as practical.
If a Standard isn't going to try to do that, what is its purpose?
> > That is *generally* true, but there are some notable exceptions such as
> > 6.5p7. That paragraph primarily affects programs whose meaning would
> > otherwise be unambiguously implied by implementations' specified storage
> > formats.
>
> No, it does not imply it. Just because data is stored in a given format does not guarantee that any particular piece of syntax is a safe way to retrieve that data. 6.5p7 is intended to tell you something about the safe ways of retrieving it, and in doing so, fails to correctly reflect what I believe to be the intent of the committee - at least, if it does reflect their intent, they need psychiatric evaluation.
In the language described by K&R, given SomeType *p, the value of *p is
entirely contained in (sizeof *p) consecutive bytes starting at the
logical address held in p. If any particular object of that type with a
particular bit pattern would have a certain value, then all objects of
that type with that same bit pattern have that value.
In the absence of 6.5p7, if the address in 'p' identifies a suitably-
sized and suitably-aligned region of storage whose bit pattern represents
a valid value of the type of *p, even evaluating *p will yield that value.
Storing a value to *p will cause the bit pattern in the storage to change
as needed so that evaluating *p would yield that value. There would only
be a few ways in which an access to *p wouldn't be a safe way to operate
on the storage identified thereby:
1. Reading or writing *p when p does not hold the address of a suitably-
sized and suitably-aligned region of accessible storage.
2. Writing to *p when the region of storage isn't writable.
3. Reading or writing *p in ways that are unsequenced with regard to
other conflicting operations on the same storage [I would view the
"restrict" qualifier as being a special case of this, since its
effect is essentially to make operations using the qualified pointer
unsequenced with regard to operations on lvalues not derived from it].
4. While not an issue for simple pointer reads/writes, operations on a
struct or union lvalue which is followed by padding may sometimes be
interpreted as operations on a slightly larger value that includes
some or all of that padding.
In the absence of 6.5p7, what other kinds of operations would be unsafe or
have an ambiguous meaning?
> > How often do such defects persist through decades of revisions?
>
> More frequently than we'd like. For instance, the definition of an expression (6.5p1) has undergone several revisions, and still remains inconsistent with normal use and the grammar production "expression" (6.5.17p1) (which is probably what it was intended to describe).
In standards outside the C Standard, how often do such defects persist?
> > What are the goals of the Committee? Does it actually have a coherent
> > goal, or do different members have different contradictory goals that
> > prevent the formation of a coherent one?
>
> It's a committee - of course it has multiple contradictory goals. However, there is a statement of the general goals that the committee has agreed to, and that statement is fairly coherent, and it falls far short of making consistency with existing implementations of C the absolute top priority that you claim it is.
I didn't say absolute top priority. On the other hand, it should have a
sufficient priority that any intentional deviation from it should be worthy
of some justification.
> > > To me, it seems patently obvious that the current wording gives
> > > undefined behavior to such accesses, and that it would be ridiculous for
> > > that to be the case. I believe that it was intended that a structure's
> > > value be modifiable by (recursively) the use of an lvalue that has the
> > > type of one of the struct's members, and which refers to a member of the
> > > structure of that type, but only so long as the modification to the
> > > struct's value are restricted to a corresponding change of that member's
> > > value.
> >
> > What is the intended purpose of having the address-of operator yield a
> > pointer of an aggregate's member type when applied to an lvalue of the
> > form aggregate.member or aggregatePtr->member? Is it to yield a pointer
> > that may be used to access an object of that type in at least some
> > circumstances? If so, in what circumstances?
>
> It's intended to be usable for that purpose anytime that no other aspect of the program gives such code undefined behavior (as would be the case if, for instance, the containing object's lifetime had expired, so the pointer was no longer valid).
If that is the intention, 6.5p7 both as written and as interpreted by gcc
and clang, contract it.
> Why do you ask? Dereferencing a pointer to a member is just as valid a way to create an lvalue referring to that member as using the member selection operator. And both approaches have undefined behavior according to 6.5p7 in most circumstances, which could not possibly have been the intent of sane committee members.
I think the Committee certainly intended that *some* uses of the derived
pointer would be UB, even within the lifetime of the parent object. The
Standard says nothing, however, that would distinguish the uses that have
defined behavior from those that don't. On the other hand, the rationale
would suggest that the intention was to avoid requiring compiler to treat
as defined behavior things that programmers weren't actually going to do.
It's possible this omission was intentional, but that the Committee
expected that compiler writers' judgment as to superior to their own with
regard to what constructs should be supported in a compiler targeting a
particular platform and application field. Such viewpoint, however,
would imply that compiler vendors have a responsibility to support
programmers' needs without regard for whether the Standard mandates it.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2018-04-18 17:29 +0000 |
| Message-ID | <UfLBC.591$pK.177@fx13.iad> |
| In reply to | #129411 |
supercat@casperkitty.com writes: >On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5, james...@verizon.net wrote= >> Does it need to? Why? It tells you how to determine what a conforming imp= >lementation of C is or is not required to do when attempting to translate a= >ny given program. Why do you need to label some programs as "standard" C co= >de, and others as not being standard? > >I would suggest that a major purpose of the Standard should be to make it >possible for compiler writers to produce implementations that may be safely >fed as wide a variety of programs as practical, and for programmers to >write programs that may be safely fed to as wide a variety of implementatio= >ns >as practical. Seems to me the C standard has been very successful as it has made it possible for compiler writers to produce implementations that may be safely fed as wide a variety of programs as practical, and for programmers to write programs that may be safely fed to as wide a variety of implementations as practical. _practical_ being the key word here.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 10:47 -0700 |
| Message-ID | <6d763f7d-ec13-4c2e-a662-53938652f4f5@googlegroups.com> |
| In reply to | #129416 |
On Wednesday, April 18, 2018 at 12:29:33 PM UTC-5, Scott Lurndal wrote: > supercat@casperkitty.com writes: > >On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5, james...@verizon.net wrote= > > >> Does it need to? Why? It tells you how to determine what a conforming imp= > >lementation of C is or is not required to do when attempting to translate a= > >ny given program. Why do you need to label some programs as "standard" C co= > >de, and others as not being standard? > > > >I would suggest that a major purpose of the Standard should be to make it > >possible for compiler writers to produce implementations that may be safely > >fed as wide a variety of programs as practical, and for programmers to > >write programs that may be safely fed to as wide a variety of implementatio= > >ns > >as practical. > > Seems to me the C standard has been very successful as it has made it > possible for compiler writers to produce implementations that may be safely > fed as wide a variety of programs as practical, and for programmers to > write programs that may be safely fed to as wide a variety of implementations > as practical. > > _practical_ being the key word here. They haven't maximized the range of program/implementation combinations where feeding a program to an implementation would be *safe*. If a program would work on 5% of implementations, but be rejected at compile time by the remaining 95%, it could be safely fed to all of those implementations. By contrast, if it would work most of the time on 100%, but might rarely create security vulnerabilities if used on an impossible-to-identify 1%, it couldn't be used safely on any of them. Note that if a program contains directives that would force it to be rejected by any implementation that couldn't process it in defined fashion, feeding the program to an implementation would be an easier and more reliable way of judging compatibility than having to read through human-readable documentation of the program and implementation to figure out whether an implementation defines all the behaviors that the program needs.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2018-04-18 20:04 +0100 |
| Message-ID | <UEMBC.446042$3o5.1599@fx20.am4> |
| In reply to | #129416 |
On 18/04/2018 18:29, Scott Lurndal wrote: > supercat@casperkitty.com writes: >> On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5, james...@verizon.net wrote= > >>> Does it need to? Why? It tells you how to determine what a conforming imp= >> lementation of C is or is not required to do when attempting to translate a= >> ny given program. Why do you need to label some programs as "standard" C co= >> de, and others as not being standard? >> >> I would suggest that a major purpose of the Standard should be to make it >> possible for compiler writers to produce implementations that may be safely >> fed as wide a variety of programs as practical, and for programmers to >> write programs that may be safely fed to as wide a variety of implementatio= >> ns >> as practical. > > Seems to me the C standard has been very successful as it has made it > possible for compiler writers to produce implementations that may be safely > fed as wide a variety of programs as practical, and for programmers to > write programs that may be safely fed to as wide a variety of implementations > as practical. > > _practical_ being the key word here. I wonder how many people regularly run their code through half a dozen different C compilers to make sure it actually is portable across implementations? (As I used to, actually.) And if they do, how often does that result in code full of dedicated #ifs and #ifdefs for each compiler? I don't think C is quite as portable as is made out. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-18 10:48 -0700 |
| Message-ID | <56c99248-dc1d-428b-b0b7-c262c1b1c5b5@googlegroups.com> |
| In reply to | #129411 |
On Wednesday, April 18, 2018 at 12:24:01 PM UTC-4, supe...@casperkitty.com wrote: > On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5, james...@verizon.net wrote: > > On Monday, April 16, 2018 at 7:22:34 PM UTC-4, supe...@casperkitty.com wrote: ... > I would suggest that a major purpose of the Standard should be to make it > possible for compiler writers to produce implementations that may be safely > fed as wide a variety of programs as practical, and for programmers to > write programs that may be safely fed to as wide a variety of implementations > as practical. The committee has clearly rejected that proposal, since the C standard doesn't do that. > If a Standard isn't going to try to do that, what is its purpose? To provide developers ways of determining whether or not a program may be safely fed to a given implementation (something that, in many cases, requires reading the documentation that the standard requires the implementation to provide, unless you go out of your way to avoid code with unspecified behavior, which is pretty hard to do). To provide implementors with ways of determining which programs must be safely feedable to that implementation (and they have considerable freedom to customize their implementations in ways that limit that set). > > > That is *generally* true, but there are some notable exceptions such as > > > 6.5p7. That paragraph primarily affects programs whose meaning would > > > otherwise be unambiguously implied by implementations' specified storage > > > formats. > > > > No, it does not imply it. Just because data is stored in a given format > > does not guarantee that any particular piece of syntax is a safe way to > > retrieve that data. 6.5p7 is intended to tell you something about the safe > > ways of retrieving it, and in doing so, fails to correctly reflect what I > > believe to be the intent of the committee - at least, if it does reflect > > their intent, they need psychiatric evaluation. > > In the language described by K&R, given SomeType *p, the value of *p is > entirely contained in (sizeof *p) consecutive bytes starting at the > logical address held in p. If any particular object of that type with a > particular bit pattern would have a certain value, then all objects of > that type with that same bit pattern have that value. In standard C, an implementation is often free to optimize the code by storing the current value of *p only in a particular register, with the intention of returning it (possibly with changes) to the proper location at a later time. Code generated by a compiler targeting a memory-poor platform might be in the middle of using the xor trick to swap the value of *p with the value of some other variable at the time you dereference *p. 6.5p7 limits that freedom, making it feasible to write code that uses *p without having to worry about those issues (so long as you do worry about conforming to the requirements of 6.5p7). I'm not sure what K&R said that might have allowed or disallowed such optimizations, but they are very much a standard part of modern C implementations. > > > How often do such defects persist through decades of revisions? > > > > More frequently than we'd like. For instance, the definition of an > > expression (6.5p1) has undergone several revisions, and still remains > > inconsistent with normal use and the grammar production "expression" > > (6.5.17p1) (which is probably what it was intended to describe). > > In standards outside the C Standard, how often do such defects persist? The only other standards I'm at all familiar with are the C++ standard, ISO 60559, and ISO 8601. Of those, the C++ standard is the only one with complexity comparable to that of the C standard, and it has at least as many problems of that kind as the C standard (probably more, being a significantly more complicated standard). > > > What are the goals of the Committee? Does it actually have a coherent > > > goal, or do different members have different contradictory goals that > > > prevent the formation of a coherent one? > > > > It's a committee - of course it has multiple contradictory goals. However, > > there is a statement of the general goals that the committee has agreed to, > > and that statement is fairly coherent, and it falls far short of making > > consistency with existing implementations of C the absolute top priority > > that you claim it is. > > I didn't say absolute top priority. You've frequently objected to language changes because they violated that goal, which were motivated by other priorities that the committee considered sufficiently important to justify those changes. This implies, at a minimum, that you disagree with the committee by believing that this goal should have been more important than those other priorities. > ... On the other hand, it should have a > sufficient priority that any intentional deviation from it should be worthy > of some justification. And that was in fact always the case - the committee found justification for all of its changes in the other priorities that it is pursing. > > > What is the intended purpose of having the address-of operator yield a > > > pointer of an aggregate's member type when applied to an lvalue of the > > > form aggregate.member or aggregatePtr->member? Is it to yield a pointer > > > that may be used to access an object of that type in at least some > > > circumstances? If so, in what circumstances? > > > > It's intended to be usable for that purpose anytime that no other aspect of > > the program gives such code undefined behavior (as would be the case if, for > > instance, the containing object's lifetime had expired, so the pointer was > > no longer valid). > If that is the intention, 6.5p7 both as written and as interpreted by gcc > and clang, contract it. "contract" => "contradict"? You've been asked to explain that claim, with example code (not rhetorical questions). I'm still waiting for you to provide it. If you don't present such example code soon, I'm going to assume that you're just talking nonsense, as usual.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 13:23 -0700 |
| Message-ID | <24ef8c07-0400-45e6-b454-d95ff37ab585@googlegroups.com> |
| In reply to | #129419 |
On Wednesday, April 18, 2018 at 12:48:48 PM UTC-5, james...@verizon.net wrote:
> On Wednesday, April 18, 2018 at 12:24:01 PM UTC-4, supe...@casperkitty.com wrote:
> > I would suggest that a major purpose of the Standard should be to make it
> > possible for compiler writers to produce implementations that may be safely
> > fed as wide a variety of programs as practical, and for programmers to
> > write programs that may be safely fed to as wide a variety of implementations
> > as practical.
>
> The committee has clearly rejected that proposal, since the C standard
> doesn't do that.
I said "should be". As it is, the Standard is basically a set of
guidelines which pretends to be a standard, but lacks the precision
necessary to really be usable as one.
> > If a Standard isn't going to try to do that, what is its purpose?
>
> To provide developers ways of determining whether or not a program may
> be safely fed to a given implementation (something that, in many cases,
> requires reading the documentation that the standard requires the
> implementation to provide, unless you go out of your way to avoid code
> with unspecified behavior, which is pretty hard to do).
Could not programmers do the same thing if the Standard simply said "An
implementation may do anything the designer sees fit, provided that it
is documented?" It seems you're setting your goals pretty low there.
I would think a good standard should seek to minimize the extent to which
programmers should need to rely upon implementations' human-readable
documentation to make such judgments.
> To provide implementors with ways of determining which programs must be
> safely feedable to that implementation (and they have considerable
> freedom to customize their implementations in ways that limit that set).
The Standard requires that implementations must be capable of processing
One Program in accordance with the Standard. Quality implementations
should of course be capable of more than that, but the Standard does not
require it.
> > In the language described by K&R, given SomeType *p, the value of *p is
> > entirely contained in (sizeof *p) consecutive bytes starting at the
> > logical address held in p. If any particular object of that type with a
> > particular bit pattern would have a certain value, then all objects of
> > that type with that same bit pattern have that value.
>
> In standard C, an implementation is often free to optimize the code by
> storing the current value of *p only in a particular register, with the
> intention of returning it (possibly with changes) to the proper location
> at a later time. Code generated by a compiler targeting a memory-poor
> platform might be in the middle of using the xor trick to swap the value
> of *p with the value of some other variable at the time you dereference
> *p. 6.5p7 limits that freedom, making it feasible to write code that
> uses *p without having to worry about those issues (so long as you do
> worry about conforming to the requirements of 6.5p7).
Certainly, the purpose of 6.5p7 is to allow compilers to cache things in
registers in cases where there is no evidence that doing so would change
program behavior. I don't think it was ever intended to suggest that
constructs that would otherwise represent evidence that register-caching
might affect program behavior should be disregarded because they weren't
explicitly listed as allowable.
> I'm not sure what K&R said that might have allowed or disallowed such optimizations, but they are very much a standard part of modern C implementations.
Of course they are, and they're fine when compilers make a bona fide effort
to recognize and avoid cases where such optimizations would be likely to
affect program behavior compared with what would result in the absence of
6.5p7. I don't think gcc and clang make any real effort at all in that
regard, since their architecture filters out evidence that would flag
optimizations as unsafe.
> > In standards outside the C Standard, how often do such defects persist?
>
> The only other standards I'm at all familiar with are the C++ standard, ISO 60559, and ISO 8601. Of those, the C++ standard is the only one with complexity comparable to that of the C standard, and it has at least as many problems of that kind as the C standard (probably more, being a significantly more complicated standard).
Given that it's derived from the C Standard, it should hardly be surprising
that the C++ Standard shares many of its problems.
> > I didn't say absolute top priority.
>
> You've frequently objected to language changes because they violated that
> goal, which were motivated by other priorities that the committee
> considered sufficiently important to justify those changes. This
> implies, at a minimum, that you disagree with the committee by believing
> that this goal should have been more important than those other
> priorities.
I regard the priority as sufficient that any violation would require
justification. My objections are generally to cases where the Standard
changes existing practice *without showing that such change is no more
disruptive than would be necessary to achieve some identifiable purpose*.
> > ... On the other hand, it should have a
> > sufficient priority that any intentional deviation from it should be worthy
> > of some justification.
>
> And that was in fact always the case - the committee found justification
> for all of its changes in the other priorities that it is pursing.
What evidence do you have that they did so in cases where they didn't
bother to articulate any justification?
> > > It's intended to be usable for that purpose anytime that no other aspect of
> > > the program gives such code undefined behavior (as would be the case if, for
> > > instance, the containing object's lifetime had expired, so the pointer was
> > > no longer valid).
>
> > If that is the intention, 6.5p7 both as written and as interpreted by gcc
> > and clang, contract it.
>
> "contract" => "contradict"?
yes.
> You've been asked to explain that claim, with example code (not
> rhetorical questions). I'm still waiting for you to provide it. If you
> don't present such example code soon, I'm going to assume that you're
> just talking nonsense, as usual.
I've added a test harness.
The claim is also contradicted by the response to DR #028.
Consider:
static int partial_test(int *p1, float *p2)
{
*p1=1;
*p2=1.0f;
return *p1;
}
union u { int i; float f;};
int test1(void)
{
union u uu;
up.i=1;
up.f=1.0f;
return up.i;
}
int test2(void)
{
union u uu;
return partial_test(&uu.i, &uu.f);
}
Under C89 and the original C99, test1() invokes Implementation-Defined
behavior; under C99 TC3 its behavior is defined in terms of the bit
representations of int and float. While I don't think there's anything
in any version of the Standard that would suggest test2() shouldn't be
equivalent to test1(), the response to DR #028 indicates test2() invokes
UB.
What difference is there between test1() and test2() that would make one
defined and one not, if not the fact that some ways of using pointers to
union members invoke UB even within the lifetime of the union objects?
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-18 14:26 -0700 |
| Message-ID | <c67e47ad-a195-42e7-9bd7-af3415a82ce4@googlegroups.com> |
| In reply to | #129430 |
On Wednesday, April 18, 2018 at 4:23:22 PM UTC-4, supe...@casperkitty.com wrote: > On Wednesday, April 18, 2018 at 12:48:48 PM UTC-5, james...@verizon.net wrote: > > On Wednesday, April 18, 2018 at 12:24:01 PM UTC-4, supe...@casperkitty.com wrote: > > > I would suggest that a major purpose of the Standard should be to make it > > > possible for compiler writers to produce implementations that may be safely > > > fed as wide a variety of programs as practical, and for programmers to > > > write programs that may be safely fed to as wide a variety of implementations > > > as practical. > > > > The committee has clearly rejected that proposal, since the C standard > > doesn't do that. > > I said "should be". As it is, the Standard is basically a set of > guidelines which pretends to be a standard, but lacks the precision > necessary to really be usable as one. > > > > If a Standard isn't going to try to do that, what is its purpose? > > > > To provide developers ways of determining whether or not a program may > > be safely fed to a given implementation (something that, in many cases, > > requires reading the documentation that the standard requires the > > implementation to provide, unless you go out of your way to avoid code > > with unspecified behavior, which is pretty hard to do). > > Could not programmers do the same thing if the Standard simply said "An > implementation may do anything the designer sees fit, provided that it > is documented?" No, giving implementations a lot of freedom is only one of the goals. Giving developers a lot of things that they can rely on is one of the other goals. The actual standard balances those goals (and several others) in a way that the Committee considered acceptable, and which has made C one of the most widely used languages in the world. Strictly conforming code is too strictly restricted to be useful. However, if you ignore what 5.2.4.1p1 actually says, and treat the lower limits mentioned there as upper limits for your code, you can actually write a fair amount of useful code withing those limits that has no syntax errors, no constraint violations, and no undefined behavior. Since 5.2.4.1p1 does actually say what it says, such code is not guaranteed to be translated and correctly executed; but as a practical matter such code is good enough for almost all purposes. If we followed your suggestion, there would be nothing that you could write with a reasonable expectation that it would have your desired behavior without first reading the implementation's entire documentation. > ... It seems you're setting your goals pretty low there. > I would think a good standard should seek to minimize the extent to which > programmers should need to rely upon implementations' human-readable > documentation to make such judgments. I'm not setting the goals low, I was only mentioning one of the several relevant goals. You mentioned another, conflicting one. The C committee considers both goals desirable (along with many others), and has produced a standard which constitutes what the committee feels to be a reasonable compromise between all of the different goals that they're trying simultaneously to achieve. I think it's a reasonable compromise, but there's many other ways that the compromise could have been handled. That's one of the reasons why there's many different computer languages to choose from - each language's designers made a different choice about how what goals they were trying to achieve, and how much importance they attached to each of those goals. > > You've frequently objected to language changes because they violated that > > goal, which were motivated by other priorities that the committee > > considered sufficiently important to justify those changes. This > > implies, at a minimum, that you disagree with the committee by believing > > that this goal should have been more important than those other > > priorities. > > I regard the priority as sufficient that any violation would require > justification. My objections are generally to cases where the Standard > changes existing practice *without showing that such change is no more > disruptive than would be necessary to achieve some identifiable purpose*. Virtually every change you've complained about has an identifiable purpose that is it is needed to achieve. See the Rationale for those purposes. You can argue that the purpose isn't sufficient justification, but that's a judgement call, and I'm not in the least surprised that your judgement in such matters differs from that of the C committee. > > > ... On the other hand, it should have a > > > sufficient priority that any intentional deviation from it should be worthy > > > of some justification. > > > > And that was in fact always the case - the committee found justification > > for all of its changes in the other priorities that it is pursing. > > What evidence do you have that they did so in cases where they didn't > bother to articulate any justification? The fact that they made the change. Why would they bother making the change if they didn't feel it was justified? It's hard work writing up such a change, and convincing the other committee members to vote in favor of it. It would be even harder to convince them if you didn't provide them with some justification for doing so - which is why I seriously doubt the existence of any change for which no justification was given at all. The justification might never have been mentioned in any publicly available document (but the Rationale covers most of the changes that had been made at the time it was published), but I'm virtually certain some justification was given for every change, even if only in committee-internal documents. I need to catch a train. I'll address the rest of your message after I get home.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-18 15:36 -0700 |
| Message-ID | <d70523c8-9ba3-480c-9701-753508363609@googlegroups.com> |
| In reply to | #129435 |
On Wednesday, April 18, 2018 at 4:26:26 PM UTC-5, james...@verizon.net wrote: > On Wednesday, April 18, 2018 at 4:23:22 PM UTC-4, supe...@casperkitty.com wrote: > > On Wednesday, April 18, 2018 at 12:48:48 PM UTC-5, james...@verizon.net wrote: > > > To provide developers ways of determining whether or not a program may > > > be safely fed to a given implementation (something that, in many cases, > > > requires reading the documentation that the standard requires the > > > implementation to provide, unless you go out of your way to avoid code > > > with unspecified behavior, which is pretty hard to do). > > > > Could not programmers do the same thing if the Standard simply said "An > > implementation may do anything the designer sees fit, provided that it > > is documented?" > > No, giving implementations a lot of freedom is only one of the goals. Giving developers a lot of things that they can rely on is one of the other goals. The actual standard balances those goals (and several others) in a way that the Committee considered acceptable, and which has made C one of the most widely used languages in the world. C was already thriving before the Standard was ratified, so I'm not sure to what extent the Committee deserves credit for that. > Strictly conforming code is too strictly restricted to be useful. However, if you ignore what 5.2.4.1p1 actually says, and treat the lower limits mentioned there as upper limits for your code, you can actually write a fair amount of useful code withing those limits that has no syntax errors, no constraint violations, and no undefined behavior. Since 5.2.4.1p1 does actually say what it says, such code is not guaranteed to be translated and correctly executed; but as a practical matter such code is good enough for almost all purposes. > Even before the Standard, quality implementations could be expected to support more than two levels of function nesting if at all practical. Had it not been for such precedent, a compiler writer who had never seen what other compilers did or how the language was used would have no idea how much stack space a quality compiler should be expected to demand. > If we followed your suggestion, there would be nothing that you could write with a reasonable expectation that it would have your desired behavior without first reading the implementation's entire documentation. My sarcastic suggestion was essentially the state of affairs before the Standard was ratified, and yet somehow people managed to write code that could be expected to work on a wide range of microcomputer-based C compilers. > > ... It seems you're setting your goals pretty low there. > > I would think a good standard should seek to minimize the extent to which > > programmers should need to rely upon implementations' human-readable > > documentation to make such judgments. > > I'm not setting the goals low, I was only mentioning one of the several relevant goals. You mentioned another, conflicting one. The C committee considers both goals desirable (along with many others), and has produced a standard which constitutes what the committee feels to be a reasonable compromise between all of the different goals that they're trying simultaneously to achieve. I think it's a reasonable compromise, but there's many other ways that the compromise could have been handled. That's one of the reasons why there's many different computer languages to choose from - each language's designers made a different choice about how what goals they were trying to achieve, and how much importance they attached to each of those goals. The problem arises with cases where some programs require useful behaviors which are supportable at essentially zero cost by many implementations but might not be supportable on all (e.g. left-shifting a possibly-negative signed value to scale by a power of two). What should happen would be for the behavior to be usable when targeting platforms that can practically support it, but programmers should have to avoid using such behavior when targeting platforms that cannot support it. I think that's probably what the authors of the Standard intended should happen, but that's not how things have evolved. > > > You've frequently objected to language changes because they violated that > > > goal, which were motivated by other priorities that the committee > > > considered sufficiently important to justify those changes. This > > > implies, at a minimum, that you disagree with the committee by believing > > > that this goal should have been more important than those other > > > priorities. > > > > I regard the priority as sufficient that any violation would require > > justification. My objections are generally to cases where the Standard > > changes existing practice *without showing that such change is no more > > disruptive than would be necessary to achieve some identifiable purpose*. > > Virtually every change you've complained about has an identifiable purpose that is it is needed to achieve. See the Rationale for those purposes. You can argue that the purpose isn't sufficient justification, but that's a judgement call, and I'm not in the least surprised that your judgement in such matters differs from that of the C committee. In many cases, rules are written far more broadly than would be needed to satisfy the stated justification. > > > And that was in fact always the case - the committee found justification > > > for all of its changes in the other priorities that it is pursing. > > > > What evidence do you have that they did so in cases where they didn't > > bother to articulate any justification? > > The fact that they made the change. Why would they bother making the change if they didn't feel it was justified? It's hard work writing up such a change, and convincing the other committee members to vote in favor of it. It would be even harder to convince them if you didn't provide them with some justification for doing so - which is why I seriously doubt the existence of any change for which no justification was given at all. The justification might never have been mentioned in any publicly available document (but the Rationale covers most of the changes that had been made at the time it was published), but I'm virtually certain some justification was given for every change, even if only in committee-internal documents. Was any rationale given for changing the behavior of -1<<1 on a two's- complement machines which do not use padding bits (under C89, it was required to yield -2 on such machines; under C99, it invokes UB). I could see justification for changing the behavior on machines that use padding bits, or store numbers in some other format, but I don't see any rationale given at all. C99's rationale for its "effective type" rules was to "clarify" things, but the rules add complexity and clarify nothing. Compare that with simply saying that if a region of storage is modified during a particular execution a loop or function, all accesses must be visibly associated, within that execution, with lvalues of a common type. A compiler need look no further to find such an association than it would look to apply other optimizations, but if a compiler would need to look at a piece of code to apply a particular optimization, it should be required to notice evidence of association that appears within that code.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-19 10:39 -0700 |
| Message-ID | <597c8580-cada-4a28-b8a4-6a303e5e0498@googlegroups.com> |
| In reply to | #129430 |
On Wednesday, April 18, 2018 at 4:23:22 PM UTC-4, supe...@casperkitty.com wrote:
> On Wednesday, April 18, 2018 at 12:48:48 PM UTC-5, james...@verizon.net wrote:
> > On Wednesday, April 18, 2018 at 12:24:01 PM UTC-4, supe...@casperkitty.com wrote:
...
[Snippage reinstated, to provide context and attributions:]
> > > On Tuesday, April 17, 2018 at 10:23:59 PM UTC-5,
> > > james...@verizon.net wrote:
> > > > On Monday, April 16, 2018 at 7:22:34 PM UTC-4,\
> > > > supe...@casperkitty.com wrote:
> > > > > What is the intended purpose of having the address-of operator
> > > > > yield a pointer of an aggregate's member type when applied to
> > > > > an lvalue of the form aggregate.member or
> > > > > aggregatePtr->member? Is it to yield a pointer that may be
> > > > > used to access an object of that type in at least some
> > > > > circumstances? If so, in what circumstances?
...
> > > > It's intended to be usable for that purpose anytime that no
> > > > other aspect of the program gives such code undefined behavior
> > > > (as would be the case if, for instance, the containing object's
> > > > lifetime had expired, so the pointer was no longer valid).
> >
> > > If that is the intention, 6.5p7 both as written and as
> > > interpreted by gcc and clang, contract it.
> >
> > "contract" => "contradict"?
>
> yes.
OK. Thanks to Keith, I was able to confirm the behavior of gcc that
you're talking about, and I was able to track down relevant gcc bug
reports. I'm not sure which of the participants of the discussion are
official representatives the gcc maintainers, but at least some of the participants (Richard Henderson, Wolfgang Bangerth) do seem to
incorrectly interpret 6.5.2.3p5 as not applying in this case, and 6.5p7
as giving permission for gcc's behavior. However, I would deny that the
standard as currently written permits that interpretation. Wolfgang also
appears to believe that if the interpretation which I believe is
correct, were correct, it would disable a substantial number of
optimization opportunities. After Tim prompted me to think about it a
bit more, I have to disagree with that assessment.
For bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892>, Andrew
Pinski argues that this interpretations would render strict aliasing
meaningless, it would have to be disabled for all struct types, but
that's not the case.
> > You've been asked to explain that claim, with example code (not
> > rhetorical questions). I'm still waiting for you to provide it. If you
> > don't present such example code soon, I'm going to assume that you're
> > just talking nonsense, as usual.
>
> I've added a test harness.
>
> The claim is also contradicted by the response to DR #028.
>
> Consider:
>
> static int partial_test(int *p1, float *p2)
> {
> *p1=1;
> *p2=1.0f;
> return *p1;
> }
>
> union u { int i; float f;};
> int test1(void)
> {
> union u uu;
> up.i=1;
> up.f=1.0f;
> return up.i;
> }
> int test2(void)
> {
> union u uu;
> return partial_test(&uu.i, &uu.f);
> }
>
> Under C89 and the original C99, test1() invokes Implementation-
> Defined behavior; under C99 TC3 its behavior is defined in terms of
> the bit representations of int and float. While I don't think there's
> anything in any version of the Standard that would suggest test2()
> shouldn't be equivalent to test1(), the response to DR #028 indicates
> test2() invokes UB.
>
> What difference is there between test1() and test2() that would make
> one defined and one not, if not the fact that some ways of using
> pointers to union members invoke UB even within the lifetime of the
> union objects?
Well, a key point here is that int and double are not compatible types,
whereas the case previously under discussion involved structs which
shared a common initial sequence of members with compatible types.
The key difference between test1() and test2() is that in test1(), the implementation knows it's dealing with a union. In test2(),
partial_test() is called, and partial_test() doesn't know that it's
being called with two different members of the same union. Mandating
that partial_test() deal with this case properly could only be done by
effectively prohibiting ALL optimizations that rely upon the assumption
that pointers to incompatible types can't alias each other - and that's
an awful lot of missed optimization opportunities.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-04-19 12:42 -0700 |
| Message-ID | <4bc0468f-9a67-4408-a6f4-1789e117b6cf@googlegroups.com> |
| In reply to | #129458 |
On Thursday, April 19, 2018 at 12:40:11 PM UTC-5, james...@verizon.net wrote:
> OK. Thanks to Keith, I was able to confirm the behavior of gcc that
> you're talking about, and I was able to track down relevant gcc bug
> reports. I'm not sure which of the participants of the discussion are
> official representatives the gcc maintainers, but at least some of the participants (Richard Henderson, Wolfgang Bangerth) do seem to
> incorrectly interpret 6.5.2.3p5 as not applying in this case, and 6.5p7
> as giving permission for gcc's behavior. However, I would deny that the
> standard as currently written permits that interpretation. Wolfgang also
> appears to believe that if the interpretation which I believe is
> correct, were correct, it would disable a substantial number of
> optimization opportunities. After Tim prompted me to think about it a
> bit more, I have to disagree with that assessment.
> For bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892>, Andrew
> Pinski argues that this interpretations would render strict aliasing
> meaningless, it would have to be disabled for all struct types, but
> that's not the case.
What is necessary to enable simple, efficient, optimization is to observe
when an lvalue L of one type is used to derive an lvalue D of another, and
accommodate situations where all accesses to a region of storage using D,
or anything derived from D, precede the first of that following:
1. An access to the storage is performed with an lvalue not derived from
D.
2. An lvalue, not derived from D, is constructed that will later be used
to access the storage, or construct another that will do so.
3. Execution reaches the start of a function or loop wherein one of the
above occurs.
None of those conditions is hard to identify.
> > The claim is also contradicted by the response to DR #028.
> >
> > Consider:
> >
> > static int partial_test(int *p1, float *p2)
> > {
> > *p1=1;
> > *p2=1.0f;
> > return *p1;
> > }
> >
> > union u { int i; float f;};
> > int test1(void)
> > {
> > union u uu;
> > up.i=1;
> > up.f=1.0f;
> > return up.i;
> > }
> > int test2(void)
> > {
> > union u uu;
> > return partial_test(&uu.i, &uu.f);
> > }
> >
> > Under C89 and the original C99, test1() invokes Implementation-
> > Defined behavior; under C99 TC3 its behavior is defined in terms of
> > the bit representations of int and float. While I don't think there's
> > anything in any version of the Standard that would suggest test2()
> > shouldn't be equivalent to test1(), the response to DR #028 indicates
> > test2() invokes UB.
> >
> > What difference is there between test1() and test2() that would make
> > one defined and one not, if not the fact that some ways of using
> > pointers to union members invoke UB even within the lifetime of the
> > union objects?
>
> Well, a key point here is that int and double are not compatible types,
> whereas the case previously under discussion involved structs which
> shared a common initial sequence of members with compatible types.
The fact that the types has different representation means that writing
one union member and reading another has *IMPLEMENTATION-DEFINED* behavior.
There is nothing in the Standard that would suggest that an action which
should be equivalent to one that invokes Implementation-Defined behavior
invokes UB.
The example could have been improved by changing partial_test to:
void partial_test(int *ip, float *fp, int mode)
{
*ip = 1;
*fp = 12.34f;
if (mode) *ip = 1;
}
If ip and fp were both members of the same union object, then the second
write to *ip could be significant, but if they don't occupy the same
storage then the conditional test, the second write, and any side-effect
free aspects of the computation of "mode", could be omitted.
I would suggest that the second version of partial_test should be regarded
as invoking UB if the two pointers alias because there is nothing within
that code that would suggest that both derive from a common type. If,
however, the code had been:
void partial_test2(int *ip, int *ip2, int mode)
{
*ip = 1;
*(float*)ip2 = 12.34f;
if (mode) *ip = 1;
}
then a compiler should be able to see that the pointer yielded by the
cast is derived from an int*, and may thus interact with other operations
on type "int".
> The key difference between test1() and test2() is that in test1(), the implementation knows it's dealing with a union. In test2(),
> partial_test() is called, and partial_test() doesn't know that it's
> being called with two different members of the same union. Mandating
> that partial_test() deal with this case properly could only be done by
> effectively prohibiting ALL optimizations that rely upon the assumption
> that pointers to incompatible types can't alias each other - and that's
> an awful lot of missed optimization opportunities.
My point was that DR #028 contradicts the claim that a pointer to an
aggregate member may be used to access that member without restriction for
that object's lifetime. If applying the address-of operator to an
aggregate member is going to yield a pointer of that member's type, the
pointer should be useful in at least *some* circumstances, but the Standard
totally fails to say what those circumstances are, and the Effective Type
rules add extra complexity [e.g. by requiring that compilers allow for
aliasing in partial_test2 above] while doing nothing to clarify the more
fundamental issue.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-04-16 21:29 -0700 |
| Message-ID | <kfno9ii8ngz.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #129101 |
I wanted to let you know I have started on a response but it isn't ready yet.
[toc] | [prev] | [next] | [standalone]
Page 7 of 8 — ← Prev page 1 2 3 4 5 6 [7] 8 Next page →
Back to top | Article view | comp.lang.c
csiph-web