Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #29128 > unrolled thread
| Started by | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| First post | 2012-12-10 17:14 +0000 |
| Last post | 2012-12-10 20:20 -0500 |
| Articles | 20 on this page of 152 — 23 participants |
Back to article view | Back to comp.lang.c
Pointer Arithmetic & UB Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-12-10 17:14 +0000
Re: Pointer Arithmetic & UB "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-12-10 09:35 -0800
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-10 12:55 -0500
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-10 13:25 -0500
Re: Pointer Arithmetic & UB falk@rahul.net (Edward A. Falk) - 2012-12-11 00:46 +0000
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-10 21:28 -0500
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-12 14:36 -0500
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-12 20:35 +0000
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-12 15:57 -0500
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-12 16:02 -0500
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-12 16:13 -0500
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-12 21:18 -0500
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-12 22:42 -0500
Re: Pointer Arithmetic & UB Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-12-17 12:04 +0200
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-17 08:47 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-17 14:58 +0000
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-17 10:59 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-17 17:26 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-17 19:33 -0500
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-20 11:00 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-20 10:03 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-20 22:02 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-21 13:09 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-21 22:40 +0000
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-21 23:39 -0500
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-22 06:50 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-22 00:15 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-22 10:34 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-22 09:32 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-23 09:38 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-23 09:55 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-26 13:35 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-27 09:03 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-27 21:31 -0500
Re: Pointer Arithmetic & UB Philip Lantz <prl@canterey.us> - 2012-12-28 01:55 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-29 13:43 -0800
Re: Pointer Arithmetic & UB Philip Lantz <prl@canterey.us> - 2012-12-28 01:39 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-28 11:31 +0000
Re: Pointer Arithmetic & UB Keith Thompson <kst-u@mib.org> - 2012-12-28 08:47 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-29 17:45 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-30 04:06 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-02 10:08 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-26 13:29 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-27 07:55 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-27 08:01 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-27 21:10 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-29 18:03 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-23 03:48 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-23 10:22 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-27 10:34 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-27 10:16 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-10 17:26 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-12 12:38 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-12 20:50 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-13 13:07 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-13 22:11 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-14 11:11 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-12 18:32 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-13 00:34 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-13 16:40 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-14 00:01 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-13 19:20 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-14 01:03 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-13 20:41 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-14 03:19 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-13 23:36 -0500
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-13 23:43 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-14 13:20 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-14 20:02 -0500
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-15 21:20 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-14 10:23 -0800
Re: Pointer Arithmetic & UB 88888 Dihedral <dihedral88888@googlemail.com> - 2013-01-15 10:53 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-15 22:39 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-15 22:28 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-15 23:35 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-16 23:38 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-18 09:37 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-14 10:29 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-15 21:38 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-15 23:57 -0800
Re: Pointer Arithmetic & UB Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-16 15:34 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-16 11:15 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-16 10:28 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-16 19:09 +0000
Re: Pointer Arithmetic & UB Richard Damon <news.x.richarddamon@xoxy.net> - 2013-01-16 23:26 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-18 10:08 -0800
Re: Pointer Arithmetic & UB Keith Thompson <kst-u@mib.org> - 2013-01-18 11:33 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-18 14:00 -0800
Re: Pointer Arithmetic & UB Richard Damon <news.x.richarddamon@xoxy.net> - 2013-01-19 09:10 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-20 13:35 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-20 20:15 -0500
Re: Pointer Arithmetic & UB Richard Damon <news.x.richarddamon@xoxy.net> - 2013-01-20 21:05 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 09:43 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-18 11:13 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-18 20:59 +0000
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2013-01-18 16:24 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-19 00:17 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-19 11:22 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-20 14:51 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-21 00:07 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 10:05 -0800
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-21 20:19 +0000
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-21 23:20 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2013-01-18 17:48 -0500
Re: Pointer Arithmetic & UB 88888 Dihedral <dihedral88888@googlemail.com> - 2013-01-18 13:13 -0800
Re: Pointer Arithmetic & UB Robert Wessel <robertwessel2@yahoo.com> - 2012-12-20 12:21 -0600
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-20 13:40 -0500
Re: Pointer Arithmetic & UB Robert Wessel <robertwessel2@yahoo.com> - 2012-12-20 13:32 -0600
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-20 14:58 -0500
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-20 21:54 +0000
Re: Pointer Arithmetic & UB Lanarcam <lanarcam1@yahoo.fr> - 2012-12-20 19:49 +0100
Re: Pointer Arithmetic & UB Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-12-21 02:38 +0200
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-21 14:33 -0500
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-21 03:18 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-21 13:16 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-21 17:57 -0500
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-21 23:52 +0000
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-21 19:47 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-21 22:54 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-22 03:31 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-22 09:16 -0800
Re: Pointer Arithmetic & UB Shao Miller <sha0.miller@gmail.com> - 2012-12-24 04:23 -0500
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-27 11:07 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 02:33 -0800
Re: Pointer Arithmetic & UB Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 02:18 -0800
Re: Pointer Arithmetic & UB Noob <root@127.0.0.1> - 2012-12-11 11:36 +0100
Re: Pointer Arithmetic & UB "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-12-11 10:00 -0800
Re: Pointer Arithmetic & UB Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-12-17 12:11 +0200
Re: Pointer Arithmetic & UB Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-11 15:27 -0500
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-11 21:09 +0000
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-12 14:30 -0500
Re: Pointer Arithmetic & UB Keith Thompson <kst-u@mib.org> - 2012-12-12 11:42 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-12 17:12 -0500
Re: Pointer Arithmetic & UB Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-12-17 12:16 +0200
Re: Pointer Arithmetic & UB Prathamesh Kulkarni <bilbotheelffriend@gmail.com> - 2012-12-10 12:04 -0800
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-10 15:29 -0500
Re: Pointer Arithmetic & UB Prathamesh Kulkarni <bilbotheelffriend@gmail.com> - 2012-12-10 12:44 -0800
Re: Pointer Arithmetic & UB Prathamesh Kulkarni <bilbotheelffriend@gmail.com> - 2012-12-10 12:47 -0800
Re: Pointer Arithmetic & UB James Kuyper <jameskuyper@verizon.net> - 2012-12-10 16:02 -0500
Re: Pointer Arithmetic & UB Prathamesh Kulkarni <bilbotheelffriend@gmail.com> - 2012-12-10 13:08 -0800
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-12 14:26 -0500
Re: Pointer Arithmetic & UB Greg Martin <greg@softsprocket.com> - 2012-12-10 14:55 -0800
Re: Pointer Arithmetic & UB Sjouke Burry <s@b> - 2012-12-10 21:18 +0000
Re: Pointer Arithmetic & UB falk@rahul.net (Edward A. Falk) - 2012-12-11 00:48 +0000
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-10 21:01 +0000
Re: Pointer Arithmetic & UB Ken Brody <kenbrody@spamcop.net> - 2012-12-12 14:24 -0500
Re: Pointer Arithmetic & UB Robert Wessel <robertwessel2@yahoo.com> - 2012-12-12 14:34 -0600
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-12 20:45 +0000
Re: Pointer Arithmetic & UB Robert Wessel <robertwessel2@yahoo.com> - 2012-12-12 15:29 -0600
Re: Pointer Arithmetic & UB glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-13 02:02 +0000
Re: Pointer Arithmetic & UB Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-12-17 05:57 -0800
Re: Pointer Arithmetic & UB pete <pfiland@mindspring.com> - 2012-12-10 20:20 -0500
Page 5 of 8 — ← Prev page 1 2 3 4 [5] 6 7 8 Next page →
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2013-01-16 15:34 +0000 |
| Message-ID | <0.ee0ca3b7f0127d4ae325.20130116153452GMT.87wqvd9m5f.fsf@bsb.me.uk> |
| In reply to | #30181 |
Tim Rentsch <txr@alumni.caltech.edu> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > >> Tim Rentsch <txr@alumni.caltech.edu> writes: >> >>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>> >>>> Tim Rentsch <txr@alumni.caltech.edu> writes: >>>>> >>>>> [discussing the "other unknown side effects" related to volatile >>>>> objects] They might modify the object being read, or they might >>>>> not; they might modify some other scalar object, or they might >>>>> not; >>>> >>>> [Aside: could it? Only if it, too, is volatile I'd have thought.] >>> >>> The Standard says only that there may be other unknown side >>> effects. AFAIK the Standard puts no limitations on what those >>> other side effects might be, so they could include changes to other >>> objects, even non-volatile ones. >> >> Footnote 34 on 6.2.4 p2 seems to suggest otherwise, does it not? >> >> 2. An object exists, has a constant address, and retains >> its last-stored value throughout its lifetime.[34] >> >> 34) In the case of a volatile object, the last store need not be >> explicit in the program. >> > > An object declared volatile is allowed to change at any time, > with no explicit program actions. That's why this footnote > is there. My point is that it's worded in a very odd way. It might also say: 34) In the case of a program that declares at least one volatile object, the last store on *any* object need not be explicit in the program. Why is the current wording so very conservative? The retraining of an object's explicitly last-stored value does not apply to any object in a program that has at least one volatile, so it seems to be a rather measly clarification. > More significantly, this paragraph (and indeed almost all of the > Standard) is concerned only with what an implementation may do (or > not do). The consequences of accessing a volatile are outside the > control of, and even the knowledge of, the implementation. If > there is text in the Standard that is meant to impose limitations > outside of the domain of just implementations, that distinction > would have to be made apparent in the text. I just don't know of > any such cases (or at least I can't remember any). I don't have any trouble with that interpretation but it sets up a tension. The standard doesn't want to restrict what an implementation does in the presence of volatile accesses, but it also wants to document what is likely to happen with implementations that define more normal behaviour for volatile objects. The result is some rather coy wording. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-16 11:15 -0500 |
| Message-ID | <kd6jmn$ot9$1@dont-email.me> |
| In reply to | #30198 |
On 1/16/2013 10:34, Ben Bacarisse wrote:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>
>>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>>>
>>>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>>>>
>>>>>> [discussing the "other unknown side effects" related to volatile
>>>>>> objects] They might modify the object being read, or they might
>>>>>> not; they might modify some other scalar object, or they might
>>>>>> not;
>>>>>
>>>>> [Aside: could it? Only if it, too, is volatile I'd have thought.]
>>>>
>>>> The Standard says only that there may be other unknown side
>>>> effects. AFAIK the Standard puts no limitations on what those
>>>> other side effects might be, so they could include changes to other
>>>> objects, even non-volatile ones.
>>>
>>> Footnote 34 on 6.2.4 p2 seems to suggest otherwise, does it not?
>>>
>>> 2. An object exists, has a constant address, and retains
>>> its last-stored value throughout its lifetime.[34]
>>>
>>> 34) In the case of a volatile object, the last store need not be
>>> explicit in the program.
>>>
>>
>> An object declared volatile is allowed to change at any time,
>> with no explicit program actions. That's why this footnote
>> is there.
>
> My point is that it's worded in a very odd way. It might also say:
>
> 34) In the case of a program that declares at least one volatile
> object, the last store on *any* object need not be explicit in the
> program.
>
> Why is the current wording so very conservative? The retraining of an
> object's explicitly last-stored value does not apply to any object in a
> program that has at least one volatile, so it seems to be a rather
> measly clarification.
>
>> More significantly, this paragraph (and indeed almost all of the
>> Standard) is concerned only with what an implementation may do (or
>> not do). The consequences of accessing a volatile are outside the
>> control of, and even the knowledge of, the implementation. If
>> there is text in the Standard that is meant to impose limitations
>> outside of the domain of just implementations, that distinction
>> would have to be made apparent in the text. I just don't know of
>> any such cases (or at least I can't remember any).
>
> I don't have any trouble with that interpretation but it sets up a
> tension. The standard doesn't want to restrict what an implementation
> does in the presence of volatile accesses, but it also wants to
> document what is likely to happen with implementations that define more
> normal behaviour for volatile objects. The result is some rather coy
> wording.
>
An observation regarding "restricting" an implementation:
struct s {
int a;
int b;
};
void func(void) {
volatile struct s foo;
int x;
foo.a = 0;
x = foo.a + (foo.b = 42);
}
If the implementation defines (and documents) that a modification to a
member of a volatile-qualified struct involves reading and storing to
the whole struct, then there would appear to be a side effect on the
scalar object 'foo.a' caused by the evaluation of the RHS operand of '+'
that is unsequenced relative to the evaluation of the LHS operand.
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-16 10:28 -0800 |
| Message-ID | <kfnsj619e49.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30198 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: > >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> >>> Tim Rentsch <txr@alumni.caltech.edu> writes: >>> >>>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >>>> >>>>> Tim Rentsch <txr@alumni.caltech.edu> writes: >>>>>> >>>>>> [discussing the "other unknown side effects" related to volatile >>>>>> objects] They might modify the object being read, or they might >>>>>> not; they might modify some other scalar object, or they might >>>>>> not; >>>>> >>>>> [Aside: could it? Only if it, too, is volatile I'd have thought.] >>>> >>>> The Standard says only that there may be other unknown side >>>> effects. AFAIK the Standard puts no limitations on what those >>>> other side effects might be, so they could include changes to other >>>> objects, even non-volatile ones. >>> >>> Footnote 34 on 6.2.4 p2 seems to suggest otherwise, does it not? >>> >>> 2. An object exists, has a constant address, and retains >>> its last-stored value throughout its lifetime.[34] >>> >>> 34) In the case of a volatile object, the last store need not be >>> explicit in the program. >>> >> >> An object declared volatile is allowed to change at any time, >> with no explicit program actions. That's why this footnote >> is there. > > My point is that it's worded in a very odd way. It might also say: > > 34) In the case of a program that declares at least one volatile > object, the last store on *any* object need not be explicit in the > program. > > Why is the current wording so very conservative? The retraining of an > object's explicitly last-stored value does not apply to any object in a > program that has at least one volatile, so it seems to be a rather > measly clarification. Oh, but that's not true. An object declared volatile may change at any time no matter what else the program is doing. An object not declared volatile might "spontaneously" change _only when there is an access to a volatile-qualified object_. Merely _declaring_ a volatile object doesn't have any effect on non-volatiles -- only accessing one. >> More significantly, this paragraph (and indeed almost all of the >> Standard) is concerned only with what an implementation may do (or >> not do). The consequences of accessing a volatile are outside the >> control of, and even the knowledge of, the implementation. If >> there is text in the Standard that is meant to impose limitations >> outside of the domain of just implementations, that distinction >> would have to be made apparent in the text. I just don't know of >> any such cases (or at least I can't remember any). > > I don't have any trouble with that interpretation but it sets up a > tension. The standard doesn't want to restrict what an implementation > does in the presence of volatile accesses, but it also wants to > document what is likely to happen with implementations that define more > normal behaviour for volatile objects. The result is some rather coy > wording. What happens when a volatile object is accessed is, by definition, outside of what the Standard knows. An implementation can choose to define anything it wants, but when accessing a volatile, it must act in accordance with what the Standard stipulates. Obviously the Standard can't document something that it explicitly doesn't know about, and implementations aren't allowed to assume something (like what side effects are caused by some volatile access) that the Standard deems outside of what they know. What constitutes an access to a volatile object is implementation defined, but what happens when a volatile access occurs is not, and cannot be, defined by an implementation, because the Standard specifically allows side effects unknown to the implementation to take place, and implementations are obliged to proceed under that assumption.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-16 19:09 +0000 |
| Message-ID | <kd6tt1$l5$1@speranza.aioe.org> |
| In reply to | #30202 |
Tim Rentsch <txr@alumni.caltech.edu> wrote: (snip) > Oh, but that's not true. An object declared volatile may change at > any time no matter what else the program is doing. An object not > declared volatile might "spontaneously" change _only when there is > an access to a volatile-qualified object_. Merely _declaring_ a > volatile object doesn't have any effect on non-volatiles -- only > accessing one. (snip) > What happens when a volatile object is accessed is, by definition, > outside of what the Standard knows. An implementation can choose > to define anything it wants, but when accessing a volatile, it must > act in accordance with what the Standard stipulates. Obviously > the Standard can't document something that it explicitly doesn't > know about, I agree with that one, though in the case of multithreading, it seems to me that the standard does allow for some possibilities for variables to change at unusual times. > and implementations aren't allowed to assume something > (like what side effects are caused by some volatile access) that > the Standard deems outside of what they know. This is the one I don't agree with. An implementation might, for example, and as an extension, allow access to I/O registers. The implementation might, then, document that I/O registers should be declared volatile, and might even document that no other kinds of volatile data are supported. > What constitutes an access to a volatile object is > implementation defined, but what happens when a volatile > access occurs is not, and cannot be, Why can't the implementation define exactly what types of volatile access it allows? > defined by an implementation, because the Standard specifically > allows side effects unknown to the implementation to take place, > and implementations are obliged to proceed under that assumption. OK, then, the implementation can, as an extension to the standard, define which types of volatile access it allow and which ones it doesn't. That would be especially useful for an implementation that, as an extension, added ways for varaibles to change other than the usual ones. -------------------- PL/I has the ABNORMAL attribute, similar to "volatile" in that it allows for a variable to change at unexpected times. But then PL/I has supported multitasking pretty much from the beginning, which allows for a way to change a variable that another task can read. Then again, last time I looked the compilers ignored the attribute. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <news.x.richarddamon@xoxy.net> |
|---|---|
| Date | 2013-01-16 23:26 -0500 |
| Message-ID | <kd7uh6$kol$1@dont-email.me> |
| In reply to | #30207 |
On 1/16/13 2:09 PM, glen herrmannsfeldt wrote:
> This is the one I don't agree with. An implementation might,
> for example, and as an extension, allow access to I/O registers.
> The implementation might, then, document that I/O registers should
> be declared volatile, and might even document that no other kinds
> of volatile data are supported.
I don't think that this would be a conforming implementation. A program
is allowed to take the address of and object of type T, convert that T*
pointer (implicitly) to a volatile T*, and then dereference it with
defined behavior. (similar to converting a T* to a const T*).
This implies that the access through a pointer to volatile needs to be
somewhat similar in effect as a non-volatile access. Since, in general,
the implementation can't know when passed a pointer to volatile if the
object pointer to is truly volatile or not it becomes hard to make the
definition of access dependent on that.
Also, I don't believe that an implementation can fail to translate
something like
struct foo {
int i;
volatile int v;
} myfoo;
...
myfoo.v = 1;
(i.e., a believe that it is allowed to arbitrarily make give any object
a volatile modifier).
What the implementation would be allowed to do (I believe) is to reserve
certain "addresses" (values of pointers) as something special, and only
decode that "specialness" for volatiles, thus normal pointer access
would not be slowed down (but not "work" for these addresses, but
volatile pointer access to these special addresses could be converted to
a different instruction to access a different I/O space.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-18 10:08 -0800 |
| Message-ID | <kfn38xy9xf2.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30233 |
Richard Damon <news.x.richarddamon@xoxy.net> writes:
> [snip] A program
> is allowed to take the address of and object of type T, convert that T*
> pointer (implicitly) to a volatile T*, and then dereference it with
> defined behavior. (similar to converting a T* to a const T*).
>
> This implies that the access through a pointer to volatile needs to be
> somewhat similar in effect as a non-volatile access. Since, in general,
> the implementation can't know when passed a pointer to volatile if the
> object pointer to is truly volatile or not it becomes hard to make the
> definition of access dependent on that.
This idea isn't right. An expression that accesses an object is
subject to volatile-access semantics exactly when the lvalue that
designates the object is volatile-qualified. Whether the object
actually being accessed was declared volatile or not makes no
difference (as far as how this particular access must be performed).
> Also, I don't believe that an implementation can fail to translate
> something like
>
> struct foo {
> int i;
> volatile int v;
> } myfoo;
>
> ...
>
> myfoo.v = 1;
>
> (i.e., a believe that it is allowed to arbitrarily make give any object
> a volatile modifier).
If the implementation can prove that the assignment must be
evaluated, then strictly speaking the program doesn't have
to be accepted, because it is not strictly conforming. Not
counting that technicality though this is right.
> What the implementation would be allowed to do (I believe) is to reserve
> certain "addresses" (values of pointers) as something special, and only
> decode that "specialness" for volatiles, thus normal pointer access
> would not be slowed down (but not "work" for these addresses, but
> volatile pointer access to these special addresses could be converted to
> a different instruction to access a different I/O space.
Any access arising from a volatile-qualified lvalue must be
performed using volatile-access semantics, whether the address
is "in range" or not. Unless there is an actual declaration for
a variable (aka object) at such an address, and which includes a
volatile qualifier, then the implementation must allow access
through an lvalue that is not volatile-qualified as well as a
volatile-qualified one. Moreover the non-volatile lvalues must
access the same area of memory as the volatile lvalues.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-01-18 11:33 -0800 |
| Message-ID | <lnehhi9tgw.fsf@nuthaus.mib.org> |
| In reply to | #30310 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Richard Damon <news.x.richarddamon@xoxy.net> writes:
[...]
>> Also, I don't believe that an implementation can fail to translate
>> something like
>>
>> struct foo {
>> int i;
>> volatile int v;
>> } myfoo;
>>
>> ...
>>
>> myfoo.v = 1;
>>
>> (i.e., a believe that it is allowed to arbitrarily make give any object
>> a volatile modifier).
>
> If the implementation can prove that the assignment must be
> evaluated, then strictly speaking the program doesn't have
> to be accepted, because it is not strictly conforming. Not
> counting that technicality though this is right.
Are you saying that an implementation is free to reject a program just
because it's not strictly conforming?
4p6 (quoting N1570) does say:
A *conforming hosted implementation* shall accept any strictly
conforming program. A *conforming freestanding implementation*
shall accept any strictly conforming program in which [SNIP]
which could be taken to imply that an implementation needn't accept a
program that's not strictly conforming.
But paragraph 3 says:
A program that is correct in all other aspects, operating on correct
data, containing unspecified behavior shall be a correct program
and act in accordance with 5.1.2.3.
A program can't "act in accordance with 5.1.2.3" if the implementation
doesn't accept it.
A concrete example: I don't believe a conforming hosted implementation
may reject this:
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("INT_MAX = %d\n", INT_MAX);
return 0;
}
even though it's not strictly conforming.
--
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 | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-18 14:00 -0800 |
| Message-ID | <kfnpq12883r.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30316 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> Richard Damon <news.x.richarddamon@xoxy.net> writes:
> [...]
>>> Also, I don't believe that an implementation can fail to translate
>>> something like
>>>
>>> struct foo {
>>> int i;
>>> volatile int v;
>>> } myfoo;
>>>
>>> ...
>>>
>>> myfoo.v = 1;
>>>
>>> (i.e., a believe that it is allowed to arbitrarily make give any object
>>> a volatile modifier).
>>
>> If the implementation can prove that the assignment must be
>> evaluated, then strictly speaking the program doesn't have
>> to be accepted, because it is not strictly conforming. Not
>> counting that technicality though this is right.
>
> Are you saying that an implementation is free to reject a program just
> because it's not strictly conforming?
>
> 4p6 (quoting N1570) does say:
>
> A *conforming hosted implementation* shall accept any strictly
> conforming program. A *conforming freestanding implementation*
> shall accept any strictly conforming program in which [SNIP]
>
> which could be taken to imply that an implementation needn't accept a
> program that's not strictly conforming.
>
> But paragraph 3 says:
>
> A program that is correct in all other aspects, operating on correct
> data, containing unspecified behavior shall be a correct program
> and act in accordance with 5.1.2.3.
>
> A program can't "act in accordance with 5.1.2.3" if the implementation
> doesn't accept it.
>
> A concrete example: I don't believe a conforming hosted implementation
> may reject this:
>
> #include <stdio.h>
> #include <limits.h>
> int main(void) {
> printf("INT_MAX = %d\n", INT_MAX);
> return 0;
> }
>
> even though it's not strictly conforming.
In fact I do believe that implementations are obliged to accept
only those programs that are strictly conforming, and may choose
not to accept (or "reject", if that means the same as not accept)
any programs that aren't.
I think the point of section 4 p3 is only to say that unspecified
behavior is not the same as undefined behavior (ie, unspecified
behavior is not completely constrained, but it does have limits,
and those limits must be observed).
I also think a not-completely-unreasonable argument supporting
that viewpoint (ie, that NSC programs need not be accepted) could
be made based on either (a) the exempting phrase "correct in all
other aspects", or (b) the phrasing used for a program "operating
on correct data", because programs that have not been accepted
won't be running and so they won't be operating on any data,
either correct or otherwise.
In practical terms though I don't think it matters much either
way. No sensible implementor is going to choose rejecting a
program just because it happens not to be strictly conforming, and
any implementation that does so either is not conforming or has a
QOI so low that no one would take it seriously. It's simply a
possible technical objection, and that's really all I was trying
to say, that possibly there was a technical inaccuracy.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <news.x.richarddamon@xoxy.net> |
|---|---|
| Date | 2013-01-19 09:10 -0500 |
| Message-ID | <kde9fv$iij$1@dont-email.me> |
| In reply to | #30310 |
On 1/18/13 1:08 PM, Tim Rentsch wrote:
> Richard Damon <news.x.richarddamon@xoxy.net> writes:
>
>> [snip] A program
>> is allowed to take the address of and object of type T, convert that T*
>> pointer (implicitly) to a volatile T*, and then dereference it with
>> defined behavior. (similar to converting a T* to a const T*).
>>
>> This implies that the access through a pointer to volatile needs to be
>> somewhat similar in effect as a non-volatile access. Since, in general,
>> the implementation can't know when passed a pointer to volatile if the
>> object pointer to is truly volatile or not it becomes hard to make the
>> definition of access dependent on that.
>
> This idea isn't right. An expression that accesses an object is
> subject to volatile-access semantics exactly when the lvalue that
> designates the object is volatile-qualified. Whether the object
> actually being accessed was declared volatile or not makes no
> difference (as far as how this particular access must be performed).
>
6.7.3.7 says:
An object that has volatile-qualified type may be modified in ways
unknown to the implementation or have other unknown side effects.
Therefore any expression referring to such an object shall be evaluated
strictly according to the rules of the abstract machine, as described in
5.1.2.3. Furthermore, at every sequence point the value last stored in
the object shall agree with that prescribed by the abstract machine,
except as modified by the unknown factors mentioned previously.134) What
constitutes an access to an object that has volatile-qualified type is
implementation-defined.
I read the standard as saying it is the volatile-qualified *object* that
is subject to being modified in ways unknown to the implementation.
Thus for the program snippit:
int i = 0;
int j;
volatile int* p = &i;
j = *p;
The fact that *p has a volatile qualification on it does NOT give the
implementation the right to not fetch the value that was stored in i. It
may do some extra actions so as to make sure that it gets the "current"
value of i,
>> Also, I don't believe that an implementation can fail to translate
>> something like
>>
>> struct foo {
>> int i;
>> volatile int v;
>> } myfoo;
>>
>> ...
>>
>> myfoo.v = 1;
>>
>> (i.e., a believe that it is allowed to arbitrarily make give any object
>> a volatile modifier).
>
> If the implementation can prove that the assignment must be
> evaluated, then strictly speaking the program doesn't have
> to be accepted, because it is not strictly conforming. Not
> counting that technicality though this is right.
Per the standard,
A strictly conforming program shall use only those features of the
language and library specified in this International Standard.3) It
shall not produce output dependent on any unspecified, undefined, or
implementation-defined behavior, and shall not exceed any minimum
implementation limit.
This snippet does NOT violate any of those conditions. The behavior of
myfoo.v = 1 IS defined by the standard, what is implementation defined
is if this constitutes an "access" to a volatile-qualified object, and
thus might be modified beyond the knowledge of the implementation.
>
>> What the implementation would be allowed to do (I believe) is to reserve
>> certain "addresses" (values of pointers) as something special, and only
>> decode that "specialness" for volatiles, thus normal pointer access
>> would not be slowed down (but not "work" for these addresses, but
>> volatile pointer access to these special addresses could be converted to
>> a different instruction to access a different I/O space.
>
> Any access arising from a volatile-qualified lvalue must be
> performed using volatile-access semantics, whether the address
> is "in range" or not. Unless there is an actual declaration for
> a variable (aka object) at such an address, and which includes a
> volatile qualifier, then the implementation must allow access
> through an lvalue that is not volatile-qualified as well as a
> volatile-qualified one. Moreover the non-volatile lvalues must
> access the same area of memory as the volatile lvalues.
>
The standard talks of volatile object, not volatile lvalues. It appears
that if the implementation can prove that the object behing the volatile
lvalue is not actually volatile, then by the "as-if" rule, it could skip
any volatile specific operations on the access.
My comments about "in range" was dealing with the concept that an
implementation might use volatile to encode that a address was in "I/O
space" as opposed to "memory space". If this implies that placing the
address of a "normal" variable into a volatile pointer and accessing
does not get access the variable, then that is non-conforming. If the
"I/O space" is smaller than the addressable memory space, then it would
be allowed for the implementation to reserve some of the memory space
(where it will never put an object) as an alias for "I/O space", and on
a volatile access to that memory range, use the I/O space access
instruction instead of the memory access instruction.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-20 13:35 -0800 |
| Message-ID | <kfn4nib8rn4.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30348 |
Richard Damon <news.x.richarddamon@xoxy.net> writes:
> On 1/18/13 1:08 PM, Tim Rentsch wrote:
>> Richard Damon <news.x.richarddamon@xoxy.net> writes:
>>
>>> [snip] A program
>>> is allowed to take the address of and object of type T, convert that T*
>>> pointer (implicitly) to a volatile T*, and then dereference it with
>>> defined behavior. (similar to converting a T* to a const T*).
>>>
>>> This implies that the access through a pointer to volatile needs to be
>>> somewhat similar in effect as a non-volatile access. Since, in general,
>>> the implementation can't know when passed a pointer to volatile if the
>>> object pointer to is truly volatile or not it becomes hard to make the
>>> definition of access dependent on that.
>>
>> This idea isn't right. An expression that accesses an object is
>> subject to volatile-access semantics exactly when the lvalue that
>> designates the object is volatile-qualified. Whether the object
>> actually being accessed was declared volatile or not makes no
>> difference (as far as how this particular access must be performed).
>
> 6.7.3.7 says:
> An object that has volatile-qualified type may be modified in
> ways unknown to the implementation or have other unknown side
> effects. Therefore any expression referring to such an object
> shall be evaluated strictly according to the rules of the
> abstract machine, as described in 5.1.2.3. Furthermore, at
> every sequence point the value last stored in the object shall
> agree with that prescribed by the abstract machine, except as
> modified by the unknown factors mentioned previously.134) What
> constitutes an access to an object that has volatile-qualified
> type is implementation-defined.
>
> I read the standard as saying it is the volatile-qualified
> *object* that is subject to being modified in ways unknown to
> the implementation.
>
> Thus for the program snippit:
>
> int i = 0;
> int j;
> volatile int* p = &i;
> j = *p;
>
> The fact that *p has a volatile qualification on it does NOT
> give the implementation the right to not fetch the value that
> was stored in i.
I see, I partly misunderstood what you were saying. This statement
is right -- using a volatile-qualified lvalue to do an access has
to work even the declared type of the object being read or written
is not volatile-qualified (ie, if the declaration doesn't specify
volatile).
> It may do some extra actions so as to make sure that it gets
> the "current" value of i,
Here is the key part of what I thought you were talking about.
In fact the implementation is obliged to access i (when '*p' is
evaluated) in exactly the same way as if 'i' had been declared
volatile.
>>> Also, I don't believe that an implementation can fail to translate
>>> something like
>>>
>>> struct foo {
>>> int i;
>>> volatile int v;
>>> } myfoo;
>>>
>>> ...
>>>
>>> myfoo.v = 1;
>>>
>>> (i.e., a believe that it is allowed to arbitrarily make give any object
>>> a volatile modifier).
>>
>> If the implementation can prove that the assignment must be
>> evaluated, then strictly speaking the program doesn't have
>> to be accepted, because it is not strictly conforming. Not
>> counting that technicality though this is right.
>
> Per the standard,
> A strictly conforming program shall use only those features of the
> language and library specified in this International Standard.3) It
> shall not produce output dependent on any unspecified, undefined, or
> implementation-defined behavior, and shall not exceed any minimum
> implementation limit.
>
> This snippet does NOT violate any of those conditions.
It does, because the output can depend on implementation-defined
behavior.
> The behavior of myfoo.v = 1 IS defined by the standard, what is
> implementation defined is if this constitutes an "access" to a
> volatile-qualified object, and thus might be modified beyond
> the knowledge of the implementation.
First of all you have misunderstood. The phrase "What constitutes
an access to an object that has volatile-qualified type" doesn't
mean _which expressions count_ as a volatile access, but _what
actions are to be performed_ when a volatile-qualified lvalue
expression is used to access an object. Implementations don't get
to decide which expressions are subject to the rules of
volatile-qualified access -- the Standard does that. What they do
get to decide is what machine-level instructions are used to
carry out such accesses.
Second, the assertion that "The behavior of myfoo.v = 1 IS defined
by the standard" is wrong. The Standard specifically says that
objects with volatile-qualifed type "may have other unknown side
effects." The Standard places no limits on what these unknown
side effects might be, and it certainly doesn't define the behavior
of what happens when they occur.
>>> What the implementation would be allowed to do (I believe) is
>>> to reserve certain "addresses" (values of pointers) as
>>> something special, and only decode that "specialness" for
>>> volatiles, thus normal pointer access would not be slowed down
>>> (but not "work" for these addresses, but volatile pointer
>>> access to these special addresses could be converted to a
>>> different instruction to access a different I/O space.
>>
>> Any access arising from a volatile-qualified lvalue must be
>> performed using volatile-access semantics, whether the address
>> is "in range" or not. Unless there is an actual declaration for
>> a variable (aka object) at such an address, and which includes a
>> volatile qualifier, then the implementation must allow access
>> through an lvalue that is not volatile-qualified as well as a
>> volatile-qualified one. Moreover the non-volatile lvalues must
>> access the same area of memory as the volatile lvalues.
>
> The standard talks of volatile object, not volatile lvalues. It
> appears that if the implementation can prove that the object
> behing the volatile lvalue is not actually volatile, then by the
> "as-if" rule, it could skip any volatile specific operations on
> the access.
The Standard does use the term 'volatile object', but 6.7.3 p7
uses the phrase 'An object that has volatile-qualified type'.
The type here is the type of the lvalue used to do the access,
not the type used in declaring the object (which declaration
may not even exist). For the latter notion, the Standard uses
the term 'declared type'.
To see this is right, consider an example like
volatile int *port_status = (void*) 0x200;
Any accesses through *port_status must observe volatile-access
semantics just the same as any other volatile access. Another
example might use a volatile-qualified lvalue to access an
object in allocated memory, which certainly couldn't have been
declared volatile, but may be important to access using volatile
semantics because the object is in memory shared with another
process.
> My comments about "in range" was dealing with the concept that
> an implementation might use volatile to encode that a address
> was in "I/O space" as opposed to "memory space". If this
> implies that placing the address of a "normal" variable into a
> volatile pointer and accessing does not get access the variable,
> then that is non-conforming. If the "I/O space" is smaller than
> the addressable memory space, then it would be allowed for the
> implementation to reserve some of the memory space (where it
> will never put an object) as an alias for "I/O space", and on a
> volatile access to that memory range, use the I/O space access
> instruction instead of the memory access instruction.
Using a different instruction (or instructions plural) is okay,
but non-volatile accesses and volatile accesses must refer to
the same area of memory (ie, for a given address). In fact this
is basically the same as the point you made earlier with using
a volatile pointer to access a variable not declared volatile.
[toc] | [prev] | [next] | [standalone]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-20 20:15 -0500 |
| Message-ID | <kdi4r4$20a$1@dont-email.me> |
| In reply to | #30417 |
On 1/20/2013 16:35, Tim Rentsch wrote:
> Richard Damon <news.x.richarddamon@xoxy.net> writes:
>
>> On 1/18/13 1:08 PM, Tim Rentsch wrote:
>>> Richard Damon <news.x.richarddamon@xoxy.net> writes:
>>>
>>>> [snip] A program
>>>> is allowed to take the address of and object of type T, convert that T*
>>>> pointer (implicitly) to a volatile T*, and then dereference it with
>>>> defined behavior. (similar to converting a T* to a const T*).
>>>>
>>>> This implies that the access through a pointer to volatile needs to be
>>>> somewhat similar in effect as a non-volatile access. Since, in general,
>>>> the implementation can't know when passed a pointer to volatile if the
>>>> object pointer to is truly volatile or not it becomes hard to make the
>>>> definition of access dependent on that.
>>>
>>> This idea isn't right. An expression that accesses an object is
>>> subject to volatile-access semantics exactly when the lvalue that
>>> designates the object is volatile-qualified. Whether the object
>>> actually being accessed was declared volatile or not makes no
>>> difference (as far as how this particular access must be performed).
>>
>> 6.7.3.7 says:
>> An object that has volatile-qualified type may be modified in
>> ways unknown to the implementation or have other unknown side
>> effects. Therefore any expression referring to such an object
>> shall be evaluated strictly according to the rules of the
>> abstract machine, as described in 5.1.2.3. Furthermore, at
>> every sequence point the value last stored in the object shall
>> agree with that prescribed by the abstract machine, except as
>> modified by the unknown factors mentioned previously.134) What
>> constitutes an access to an object that has volatile-qualified
>> type is implementation-defined.
>>
>> I read the standard as saying it is the volatile-qualified
>> *object* that is subject to being modified in ways unknown to
>> the implementation.
>>
>> Thus for the program snippit:
>>
>> int i = 0;
>> int j;
>> volatile int* p = &i;
>> j = *p;
>>
>> The fact that *p has a volatile qualification on it does NOT
>> give the implementation the right to not fetch the value that
>> was stored in i.
>
> I see, I partly misunderstood what you were saying. This statement
> is right -- using a volatile-qualified lvalue to do an access has
> to work even [if] the declared type of the object being read or written
> is not volatile-qualified (ie, if the declaration doesn't specify
> volatile).
>
("has to work": Missing citation.)
These aren't the same statement. Yours follows for all cases from
6.5p7. "...the right to not fetch the value" applies to this particular
code example, but does not appear to apply to all cases.
>> It may do some extra actions so as to make sure that it gets
>> the "current" value of i,
>
> Here is the key part of what I thought you were talking about.
> In fact the implementation is obliged to access i (when '*p' is
> evaluated) in exactly the same way as if 'i' had been declared
> volatile.
>
("obliged to access...in...the same way": Missing citation.)
Are you thinking of the fact that this case is omitted from 6.7.3p6, or
is there something more?
>>>> Also, I don't believe that an implementation can fail to translate
>>>> something like
>>>>
>>>> struct foo {
>>>> int i;
>>>> volatile int v;
>>>> } myfoo;
>>>>
>>>> ...
>>>>
>>>> myfoo.v = 1;
>>>>
>>>> (i.e., a believe that it is allowed to arbitrarily make give any object
>>>> a volatile modifier).
>>>
>>> If the implementation can prove that the assignment must be
>>> evaluated, then strictly speaking the program doesn't have
>>> to be accepted, because it is not strictly conforming. Not
>>> counting that technicality though this is right.
>>
>> Per the standard,
>> A strictly conforming program shall use only those features of the
>> language and library specified in this International Standard.3) It
>> shall not produce output dependent on any unspecified, undefined, or
>> implementation-defined behavior, and shall not exceed any minimum
>> implementation limit.
>>
>> This snippet does NOT violate any of those conditions.
>
> It does, because the output can depend on implementation-defined
> behavior.
>
I've interpreted a previous post of yours as suggesting that, in a function:
volatile int i = 42;
int x = i + i;
the behaviour is defined and an implementation must not be concerned
with the possible, unknown side effects _on_ the volatile scalar 'i'.
Here, you've argued a technicality that translation semantics allow for
an implementation to reject Mr. Richard Damon's code because there might
be unknown side effects _on_ the volatile scalar 'myfoo.v'.
Can you please clarify? Is there something about the declaration of the
member, or about structs, that makes these different?
>> It
>> appears that if the implementation can prove that the object
>> behing the volatile lvalue is not actually volatile, then by the
>> "as-if" rule, it could skip any volatile specific operations on
>> the access.
To Mr. Richard Damon: I don't see why not. The only draw-back is that,
in my experience, usually 'volatile' is used when the programmer knows
something about how the implementation implements, and wants to tell the
implementation not to assume that the stored value will remain
consistent. So this strikes me as an inverted example: I think it's
usually the case that:
1. Non-volatile operations are the usual
2. Non-volatile operations are sometimes optimized
3. Volatile operations have to behave as #1 (so it's not exactly
"volatile-specific")
> [...discussion of declared type...]
Also (as a further note to Mr. Richard Damon), "effective type" is
sometimes used. Neither of these is referred to in 6.7.3, but p6 says
"defined with", which could include the notion of "declared type". But
that's not the "object that has" of p7, which Mr. T. Rentsch just mentioned.
p4:
"The properties associated with qualified types are meaningful only
for expressions that are lvalues.132)"
(where footnote 132 then subsequently suggests that a 'const' object
might be found in read-only memory. :) )
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <news.x.richarddamon@xoxy.net> |
|---|---|
| Date | 2013-01-20 21:05 -0500 |
| Message-ID | <kdi7p3$f9f$1@dont-email.me> |
| In reply to | #30429 |
On 1/20/13 8:15 PM, Shao Miller wrote: > On 1/20/2013 16:35, Tim Rentsch wrote: >> Richard Damon <news.x.richarddamon@xoxy.net> writes: >> >>> On 1/18/13 1:08 PM, Tim Rentsch wrote: >>>> Richard Damon <news.x.richarddamon@xoxy.net> writes: >>> It >>> appears that if the implementation can prove that the object >>> behing the volatile lvalue is not actually volatile, then by the >>> "as-if" rule, it could skip any volatile specific operations on >>> the access. > > To Mr. Richard Damon: I don't see why not. The only draw-back is that, > in my experience, usually 'volatile' is used when the programmer knows > something about how the implementation implements, and wants to tell the > implementation not to assume that the stored value will remain > consistent. So this strikes me as an inverted example: I think it's > usually the case that: > > 1. Non-volatile operations are the usual > 2. Non-volatile operations are sometimes optimized > 3. Volatile operations have to behave as #1 (so it's not exactly > "volatile-specific") > my comment relates to a code snippet like: int i = 0; volatile int *p = &i j = *p; Because here the compiler can know that the object pointed to by p is a non-volatile object, and even the value of it, the compiler is free to convert the assignment of j into j=0, and not access i, because all the reference to volatile accesses are to volatile *objects*, and in this code we have 3 object, i, p, and j, none of which are volatile. The fact that the effective type of *p is volatile int, as an lvalue, doesn't force the implementation to make the access, as the access rules refer to object. The only spot where I find a mention of the volatility of an lvalue mattering is 6.7.3p6 (and repeated in J.2) If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined. and this is the opposite of the case in question. It is probably unusual for the compiler to be able to prove that a pointer to a volatile qualified type can't be pointing to a volatile object, so this optimization probably can't happen often, but it is allowed.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-21 09:43 -0800 |
| Message-ID | <kfnr4le77q2.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30430 |
Richard Damon <news.x.richarddamon@xoxy.net> writes:
>> [snip]
>
> my comment relates to a code snippet like:
>
> int i = 0;
> volatile int *p = &i
>
> j = *p;
>
> Because here the compiler can know that the object pointed to by p is
> a non-volatile object, and even the value of it, the compiler is free
> to convert the assignment of j into j=0, and not access i, because all
> the reference to volatile accesses are to volatile *objects*, and in
> this code we have 3 object, i, p, and j, none of which are volatile.
> The fact that the effective type of *p is volatile int, as an lvalue,
> doesn't force the implementation to make the access, as the access
> rules refer to object. [snip]
Please excuse my being blunt, but your interpretation is wrong.
The C99 Rationale document says this:
If it is necessary to access a nonvolatile object using
volatile semantics, the technique is to cast the address of
the object to the appropriate pointer-to-qualified type,
then dereference that pointer.
This statement makes it clear that it is the type of the accessing
lvalue that determines whether volatile semantics are required.
Incidentally, in your example, p points to i, which is declared to
be of type int, so the effective type of the object at *p is int.
But that makes no difference to the type of the accessing lvalue,
which because it is volatile qualified forces volatile semantics.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-18 11:13 -0800 |
| Message-ID | <kfny5fq8fta.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30207 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > Tim Rentsch <txr@alumni.caltech.edu> wrote: > [snip] > >> and implementations aren't allowed to assume something (like >> what side effects are caused by some volatile access) that the >> Standard deems outside of what they know. > > This is the one I don't agree with. An implementation might, for > example, and as an extension, allow access to I/O registers. The > implementation might, then, document that I/O registers should be > declared volatile, and might even document that no other kinds of > volatile data are supported. Implementations don't get to make that choice. The volatile keyword is allowed in declaring/defining any variable, and also in type names (eg, casts or compound literals). Any expression doing an access through a volatile-qualified lvalue is obliged to perform that access under the rules that the Standard gives for the semantics of such accesses. Implementations don't get to choose which volatile-qualified accesses are "supported" and which ones aren't -- the Standard obliges them to perform them all, and without making any assumptions about what side effects might take place as a result. >> What constitutes an access to a volatile object is >> implementation defined, but what happens when a volatile >> access occurs is not, and cannot be, > > Why can't the implementation define exactly what types of > volatile access it allows? Because it isn't consistent with the requirements that all accesses be performed, and volatile-qualified accesses be performed according to how the Standard describes the semantics for such accesses. >> defined by an implementation, because the Standard specifically >> allows side effects unknown to the implementation to take place, >> and implementations are obliged to proceed under that assumption. > > OK, then, the implementation can, as an extension to the standard, > define which types of volatile access it allow and which ones it > doesn't. [snip] That simply isn't consistent with what the Standard requires. Implementations must carry out volatile-qualified accesses according to the requireed semantics; they don't get to choose which of those might be "allowed" and which aren't. It's like saying an implementation could define an extension where array indexing only works for even index values -- it cannot, because such an implementation fails to meet the requirements that the Standard otherwise imposes.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-18 20:59 +0000 |
| Message-ID | <kdcd4d$10i$1@speranza.aioe.org> |
| In reply to | #30315 |
Tim Rentsch <txr@alumni.caltech.edu> wrote: > glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: >> Tim Rentsch <txr@alumni.caltech.edu> wrote: >> [snip] >>> and implementations aren't allowed to assume something (like >>> what side effects are caused by some volatile access) that the >>> Standard deems outside of what they know. > >> This is the one I don't agree with. An implementation might, for >> example, and as an extension, allow access to I/O registers. The >> implementation might, then, document that I/O registers should be >> declared volatile, and might even document that no other kinds of >> volatile data are supported. > Implementations don't get to make that choice. The volatile > keyword is allowed in declaring/defining any variable, and also > in type names (eg, casts or compound literals). Any expression > doing an access through a volatile-qualified lvalue is obliged to > perform that access under the rules that the Standard gives for > the semantics of such accesses. Implementations don't get to > choose which volatile-qualified accesses are "supported" and > which ones aren't -- the Standard obliges them to perform them > all, and without making any assumptions about what side effects > might take place as a result. I don't say this very often, but that is just dumb. Except for the case of multithreading, which has been pretty much left out of the discussion, only the implementation knows which possible accesses need to be protected against, and how to protect against them. Someone whose name I forget used to post in comp.lang.fortran on how useless the C rules were for volatile, but I never understood why they were so useless. Now, on many processors with memory mapped I/O registers, it is simple to access one by dereferencing a pointer to a specific address. Volatile pointers and pointers (that aren't volatile) to volatile locations also have been pretty much left out of the discussion. >>> What constitutes an access to a volatile object is >>> implementation defined, but what happens when a volatile >>> access occurs is not, and cannot be, >> Why can't the implementation define exactly what types of >> volatile access it allows? > Because it isn't consistent with the requirements that all > accesses be performed, and volatile-qualified accesses be > performed according to how the Standard describes the semantics > for such accesses. There are way too many different ways to access memory, most of which only the implementation can know about. OK, say a program has: volatile int x=1; while(x) ; waiting until someone, somewhere, changes x, and, as required the implementation makes the appropriate access and, among others, doesn't optimize the loop. Now, say that the implementation has a cache such that, even though memory fetch instructions are executed it never actually gets to real memory. Maybe the user need to go to the BIOS setup and turn off caching. Yet you say that the standard understands how to do that? >>> defined by an implementation, because the Standard specifically >>> allows side effects unknown to the implementation to take place, >>> and implementations are obliged to proceed under that assumption. >> OK, then, the implementation can, as an extension to the standard, >> define which types of volatile access it allow and which ones it >> doesn't. [snip] > That simply isn't consistent with what the Standard requires. > Implementations must carry out volatile-qualified accesses > according to the requireed semantics; they don't get to choose > which of those might be "allowed" and which aren't. It's like > saying an implementation could define an extension where array > indexing only works for even index values -- it cannot, because > such an implementation fails to meet the requirements that the > Standard otherwise imposes. Probably a bad example because, with alignment restrictions, implementations can do just that. The implementation has to add the appropriate padding, as required. Fortran now has the ASYNCHRONOUS attribute, and ASYNCHRONOUS I/O statements. That is another way that variables can change at unexpected times. I know I used asynchronous I/O in SunOS C many years ago, but it wasn't in the standard, and may still not be. I previously wrote about the PL/I ABNORMAL attribute. PL/I is insteresting as, pretty much, the whole language was defined before any implementations were written. They had to anticipate what could and couldn't be implemented, and ABNORMAL has a pretty simple definition. But it is then up to the implementation to figure out what can actually happen, and what to do about it. -- glen
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2013-01-18 16:24 -0500 |
| Message-ID | <50F9BDA2.6090406@verizon.net> |
| In reply to | #30323 |
On 01/18/2013 03:59 PM, glen herrmannsfeldt wrote: > Tim Rentsch <txr@alumni.caltech.edu> wrote: ... >> ... It's like >> saying an implementation could define an extension where array >> indexing only works for even index values -- it cannot, because >> such an implementation fails to meet the requirements that the >> Standard otherwise imposes. > > Probably a bad example because, with alignment restrictions, > implementations can do just that. The implementation has to > add the appropriate padding, as required. Could you explain that in a little more detail? Could you show a case where the standard permits an implementation to treat array[i] as problematic solely because i is odd, and not for any other reason?
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-19 00:17 -0800 |
| Message-ID | <kfnlibp8u37.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30323 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > Tim Rentsch <txr@alumni.caltech.edu> wrote: >> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > >>> Tim Rentsch <txr@alumni.caltech.edu> wrote: >>> [snip] > >> Implementations don't get to make that choice. The volatile >> keyword is allowed in declaring/defining any variable, and also >> in type names (eg, casts or compound literals). Any expression >> doing an access through a volatile-qualified lvalue is obliged to >> perform that access under the rules that the Standard gives for >> the semantics of such accesses. Implementations don't get to >> choose which volatile-qualified accesses are "supported" and >> which ones aren't -- the Standard obliges them to perform them >> all, and without making any assumptions about what side effects >> might take place as a result. > > I don't say this very often, but that is just dumb. > > Except for the case of multithreading, which has been pretty > much left out of the discussion, only the implementation knows > which possible accesses need to be protected against, and how > to protect against them. [snip] Probably you are operating under an assumption that is essentially wrong, namely, that the term 'implementation' includes things like the operating system and hardware that the programs will run on. It doesn't. > Volatile pointers and pointers (that aren't volatile) to > volatile locations also have been pretty much left out of the > discussion. Volatile objects that contain pointers are accessed in the same way that volatile objects containing non-pointers are. Pointers to volatile locations are covered under the term 'volatile-qualified lvalue', which I already discussed. >>> Why can't the implementation define exactly what types of >>> volatile access it allows? >> >> Because it isn't consistent with the requirements that all >> accesses be performed, and volatile-qualified accesses be >> performed according to how the Standard describes the semantics >> for such accesses. > > There are way too many different ways to access memory, most of > which only the implementation can know about. [snip example] > Now, say that the implementation has a cache such that, even > though memory fetch instructions are executed it never actually > gets to real memory. Here again you appear to be confused about what is included under the term 'implementation'. > Maybe the user need to go to the BIOS setup and turn off > caching. Yet you say that the standard understands how to do > that? No, I said no such thing. The Standard explicitly does _not_ specify such things, and in effect requires implementations not to make any assumptions about what will happen when a volatile-qualified access is done. >> [snip] It's like >> saying an implementation could define an extension where array >> indexing only works for even index values -- it cannot, because >> such an implementation fails to meet the requirements that the >> Standard otherwise imposes. > > Probably a bad example because, with alignment restrictions, > implementations can do just that. The implementation has to > add the appropriate padding, as required. I expect you have misunderstood my example. I'm not talking about byte addresses but about the values used in index expressions. If we have a declaration like int a[10]; then all of these expressions a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] are necessarily legal expressions, and must designate the corresponding element of the array a. Questions about alignment or padding have no bearing on the issue.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-19 11:22 +0000 |
| Message-ID | <kddvm3$913$1@speranza.aioe.org> |
| In reply to | #30339 |
Tim Rentsch <txr@alumni.caltech.edu> wrote: (snip) >>> Implementations don't get to make that choice. The volatile >>> keyword is allowed in declaring/defining any variable, and also >>> in type names (eg, casts or compound literals). Any expression >>> doing an access through a volatile-qualified lvalue is obliged to >>> perform that access under the rules that the Standard gives for >>> the semantics of such accesses. Implementations don't get to >>> choose which volatile-qualified accesses are "supported" and >>> which ones aren't -- the Standard obliges them to perform them >>> all, and without making any assumptions about what side effects >>> might take place as a result. >> I don't say this very often, but that is just dumb. >> Except for the case of multithreading, which has been pretty >> much left out of the discussion, only the implementation knows >> which possible accesses need to be protected against, and how >> to protect against them. [snip] > Probably you are operating under an assumption that is > essentially wrong, namely, that the term 'implementation' > includes things like the operating system and hardware that > the programs will run on. It doesn't. OK, what I was callying implementation is a specific compiler/hardware/OS combination. Well, it used to be that compilers were written by hardware manufacturers specifically for their hardware. That doesn't happen so often anymore. So, yes, gcc running on different systems may contain most of the same source code. Now, for a large fraction of the features of the language the same compiler code can be used for almost all systems. (What do you call a specific hardware/OS/whatever-else combination that a compiler must targer? Implementations didn't seem so far off to me.) At some point, you have to get down to actual machine instructions for the target hardware, and system calls to the target OS. In many cases, the hardware differences can be parameterized, such as the number of available registers, and again common code can be used. And even more, there are some uses for volatile that might be pretty much the same for different hardware and/or OS combinations. But maybe not all. As I mentioned, some hardware might have an interlocked storage update system, and it might be that is needed for some particular implementation (that is, hardware and/or OS). Or many more things that I haven't thought about. Now, besides portable compilers like gcc and lcc there are still many that only exist for one hardware and OS. Such might even have specific features for that target to help convince users to buy one. That might include support for hardware or software features not supported by the more portable compilers, and some of those might be related to the need for volatile that don't exist on other systems. OK, so a long way to explain what I tried to mean by implementation. Either a specific purpose compiler, or a general (portable) compiler compiled for a specific hardware/OS combination. But also, as I don't seem to have explained very well, there might be reasons for specific hardware and/or OS to need something to be volatile, where other hardware and/or OS have no similar need. >> Volatile pointers and pointers (that aren't volatile) to >> volatile locations also have been pretty much left out of the >> discussion. > Volatile objects that contain pointers are accessed in the same > way that volatile objects containing non-pointers are. > Pointers to volatile locations are covered under the term > 'volatile-qualified lvalue', which I already discussed. OK, I missed that one. >>>> Why can't the implementation define exactly what types of >>>> volatile access it allows? >>> Because it isn't consistent with the requirements that all >>> accesses be performed, and volatile-qualified accesses be >>> performed according to how the Standard describes the semantics >>> for such accesses. >> There are way too many different ways to access memory, most of >> which only the implementation can know about. [snip example] >> Now, say that the implementation has a cache such that, even >> though memory fetch instructions are executed it never actually >> gets to real memory. > Here again you appear to be confused about what is included > under the term 'implementation'. >> Maybe the user need to go to the BIOS setup and turn off >> caching. Yet you say that the standard understands how to do >> that? > No, I said no such thing. The Standard explicitly does _not_ > specify such things, and in effect requires implementations > not to make any assumptions about what will happen when a > volatile-qualified access is done. But not making any assumptions IS making an assumption. It makes the assumption that the specific hardware in question behaves in the way that the standard expects. Now, in the case of an expression like i+j, and to be more specific i and j are not volatile, we have a pretty good idea what to expect. That the hardware has some ability to add two values. That is a pretty good assumption for most hardware. But say the hardware has some new feature that no hardware had before, and that requires something special from the compiler. Even more, say that the compiler is written specifically for that hardware. Now, say this feature allows certain memory locations (or maybe locations that aren't memory) to change at unexpected times. Sure sounds like volatile would be a good choice. But maybe it doesn't work exactly the way the standard says, for some strange reason. And even more, that there might not be any other use for volatile. It sure would be convenient if volatile could be used in this case. I suppose the other choice is to invent some new keyword, add it to the compiler, and confuse everyone. (snip of alignment discussion) -- glen
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-01-20 14:51 -0800 |
| Message-ID | <kfnzk0379j8.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #30344 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > Tim Rentsch <txr@alumni.caltech.edu> wrote: > (snip) > >> Probably you are operating under an assumption that is >> essentially wrong, namely, that the term 'implementation' >> includes things like the operating system and hardware that >> the programs will run on. It doesn't. > > OK, what I was callying implementation is a specific > compiler/hardware/OS combination. [snip] > > But also, as I don't seem to have explained very well, there > might be reasons for specific hardware and/or OS to need > something to be volatile, where other hardware and/or OS > have no similar need. [snip] I think you're missing a key point here. The kinds of things you're talking about are all platform specific. Implementations are free to define extensions that handle platform-specific mechanisms, even very strange ones, but there's no reason those need to involve volatile. The reason volatile exists is for cases when a developer knows things that the implementor doesn't, not the other way around. Hence, accessing a volatile is defined so that no assumptions are made about what all else might be going on, specifically because what seems like a reasonable assumption in other cases might not be true in this case -- the developer knows better than the implementor, and by using volatile is telling the implementor that this is so, so the implementation should just play dumb and do what it is told in the most direct and straightforward way it can. Exotic platform-specific stuff, where the implementation can take advantage of knowledge that a developer might not have, needn't use volatile at all, but instead can (and in many cases should) use platform-specific extensions whose semantics is determined solely by the implementation, and not constrained by the Standard. The whole point of volatile is to have a standard way of letting the implementation know that the developer knows something that the implementor doesn't. And that is precisely what makes it valuable.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2013-01-21 00:07 +0000 |
| Message-ID | <kdi0rn$qgd$1@speranza.aioe.org> |
| In reply to | #30421 |
Tim Rentsch <txr@alumni.caltech.edu> wrote: > glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: >> Tim Rentsch <txr@alumni.caltech.edu> wrote: >> (snip) (snip) >> OK, what I was callying implementation is a specific >> compiler/hardware/OS combination. [snip] >> But also, as I don't seem to have explained very well, there >> might be reasons for specific hardware and/or OS to need >> something to be volatile, where other hardware and/or OS >> have no similar need. [snip] > I think you're missing a key point here. The kinds of things > you're talking about are all platform specific. Implementations > are free to define extensions that handle platform-specific > mechanisms, even very strange ones, but there's no reason those > need to involve volatile. Well, yes, but it is sometimes necessary to have a way to tell the implementation that you are doing something unusual. > The reason volatile exists is for cases when a developer knows > things that the implementor doesn't, not the other way around. Yes, I wasn't trying to deny those, but to indicate that there might be more than that. > Hence, accessing a volatile is defined > so that no assumptions are made about what all else might be going > on, specifically because what seems like a reasonable assumption > in other cases might not be true in this case -- the developer > knows better than the implementor, and by using volatile is > telling the implementor that this is so, so the implementation > should just play dumb and do what it is told in the most direct > and straightforward way it can. Easy to say, not always so easy to do. That works fine if there are only two ways to do something, but maybe there are more? > Exotic platform-specific stuff, where the implementation can > take advantage of knowledge that a developer might not have, > needn't use volatile at all, but instead can (and in many > cases should) use platform-specific extensions whose semantics > is determined solely by the implementation, and not > constrained by the Standard. Well, ok, but everyone hates implementation specific keywords. For one, there is always the possibility that one conflicts with other uses for the word. Now, so far the only use for volatile within what is otherwise standard C is for multithreading, when one tread might change a variable that another thread is using. That seems fine to me. Anohter one mentioned is I/O registers. That is pretty much implementation specific, but the implementation needs to know when the developer is using I/O registers. I suppose one could add a new keyword for it, but others have already suggested volatile. > The whole point of volatile is to have a standard way of letting > the implementation know that the developer knows something that > the implementor doesn't. And that is precisely what makes it > valuable. Yes. But exactly what those things are might be implementation dependent. Seems to me that there is a very good chance that they are. If there are three different things that the developer might know, and need to tell the implementation about, what do you do? As I mentioned previously, one thing that you might need is interlocked access to a memory location. That seems to be similar to the need for volatile, but maybe not exactly. -- glen
[toc] | [prev] | [next] | [standalone]
Page 5 of 8 — ← Prev page 1 2 3 4 [5] 6 7 8 Next page →
Back to top | Article view | comp.lang.c
csiph-web