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


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

Pointer Arithmetic & UB

Started byEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
First post2012-12-10 17:14 +0000
Last post2012-12-10 20:20 -0500
Articles 20 on this page of 99 — 21 participants

Back to article view | Back to comp.lang.c


Contents

  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 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 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →


#29565

FromShao Miller <sha0.miller@gmail.com>
Date2012-12-21 03:18 -0500
Message-ID<kb160d$kpg$1@dont-email.me>
In reply to#29524
On 12/20/2012 11:00, Ken Brody wrote:
>
> Condensed version of the discussion so far, in this subthread:
>
> =====
>
> Given:
>
>      extern volatile int x;
>      int i = x + x;
>
> And citing several C&V from different standards regarding the fact
> merely accessing a volatile is a "side effect".
>
> Does the above invoke UB?  (No sequence point between the two "side
> effects" of accessing "x".)
>
> =====
>
> The Standard also requires (5.1.2.3p2) that all side effects be
> "complete" at the next sequence point.
>
> Given that whatever side effect the access of "x" may have is outside
> the control of the abstract machine, I fail to see how the sequence
> point requirement applies to the side effect of accessing a volatile.
>
> Consider, for example, a memory-mapped I/O system, where reading from a
> given address causes the printer to start printing whatever is in its
> buffer.  How can C enforce the "shall be complete" requirement of
> 5.1.2.3p2?  How is "i=x;i+=x;" any better than "i=x+x;"?
>

Yes, it invokes undefined behaviour.  If a read of 'x' is a side effect, 
then two reads of 'x' are two side effects that could conflict if they 
occur simultaneously.  That is, since an implementation can say that a 
read of 'x' increments a foo counter elsewhere, then two simultaneous 
reads can result in two simultaneous increments of the foo counter, 
which blows up the computer.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#29581

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-21 13:16 -0800
Message-ID<kfn4njf5cna.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29565
Shao Miller <sha0.miller@gmail.com> writes:

> On 12/20/2012 11:00, Ken Brody wrote:
>>
>> Condensed version of the discussion so far, in this subthread:
>>
>> =====
>>
>> Given:
>>
>>      extern volatile int x;
>>      int i = x + x;
>>
>> And citing several C&V from different standards regarding the fact
>> merely accessing a volatile is a "side effect".
>>
>> Does the above invoke UB?  (No sequence point between the two "side
>> effects" of accessing "x".)
>>
>> =====
>>
>> The Standard also requires (5.1.2.3p2) that all side effects be
>> "complete" at the next sequence point.
>>
>> Given that whatever side effect the access of "x" may have is outside
>> the control of the abstract machine, I fail to see how the sequence
>> point requirement applies to the side effect of accessing a volatile.
>>
>> Consider, for example, a memory-mapped I/O system, where reading from a
>> given address causes the printer to start printing whatever is in its
>> buffer.  How can C enforce the "shall be complete" requirement of
>> 5.1.2.3p2?  How is "i=x;i+=x;" any better than "i=x+x;"?
>>
>
> Yes, it invokes undefined behaviour.  If a read of 'x' is a side
> effect, then two reads of 'x' are two side effects that could conflict
> if they occur simultaneously.  That is, since an implementation can
> say that a read of 'x' increments a foo counter elsewhere, then two
> simultaneous reads can result in two simultaneous increments of the
> foo counter, which blows up the computer.

IMO this conclusion is wrong.  The consequences of volatile access (ie,
the extra-linguistic side effects) are outside the domain of 6.5p2,
because it is concerned only with program expressions, not other
unknown memory changes.  This view is explained in more detail in my
response to Ben Bacarisse in this thread.

[toc] | [prev] | [next] | [standalone]


#29586

FromShao Miller <sha0.miller@gmail.com>
Date2012-12-21 17:57 -0500
Message-ID<kb2phn$5fl$1@dont-email.me>
In reply to#29581
On 12/21/2012 16:16, Tim Rentsch wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>
>> On 12/20/2012 11:00, Ken Brody wrote:
>>>
>>> Condensed version of the discussion so far, in this subthread:
>>>
>>> =====
>>>
>>> Given:
>>>
>>>       extern volatile int x;
>>>       int i = x + x;
>>>
>>> And citing several C&V from different standards regarding the fact
>>> merely accessing a volatile is a "side effect".
>>>
>>> Does the above invoke UB?  (No sequence point between the two "side
>>> effects" of accessing "x".)
>>>
>>> =====
>>>
>>> The Standard also requires (5.1.2.3p2) that all side effects be
>>> "complete" at the next sequence point.
>>>
>>> Given that whatever side effect the access of "x" may have is outside
>>> the control of the abstract machine, I fail to see how the sequence
>>> point requirement applies to the side effect of accessing a volatile.
>>>
>>> Consider, for example, a memory-mapped I/O system, where reading from a
>>> given address causes the printer to start printing whatever is in its
>>> buffer.  How can C enforce the "shall be complete" requirement of
>>> 5.1.2.3p2?  How is "i=x;i+=x;" any better than "i=x+x;"?
>>>
>>
>> Yes, it invokes undefined behaviour.  If a read of 'x' is a side
>> effect, then two reads of 'x' are two side effects that could conflict
>> if they occur simultaneously.  That is, since an implementation can
>> say that a read of 'x' increments a foo counter elsewhere, then two
>> simultaneous reads can result in two simultaneous increments of the
>> foo counter, which blows up the computer.
>
> IMO this conclusion is wrong.  The consequences of volatile access (ie,
> the extra-linguistic side effects) are outside the domain of 6.5p2,
> because it is concerned only with program expressions, not other
> unknown memory changes.  This view is explained in more detail in my
> response to Ben Bacarisse in this thread.
>

I read the other response.  And what about if 'x' and "foo counter" are 
the same scalar?  Regardless of that or any other example, N1570's 
informative Annex I, point 2 includes:

   "An ‘‘unordered’’ binary operator (not comma, &&, or ||) contains a 
side effect to an lvalue in one operand, and a side effect to, or an 
access to the value of, the identical lvalue in the other operand (6.5)."

Informative Annex J "Portability issues", J.2 "Undefined behavior", 
point 1 includes:

   "A side effect on a scalar object is unsequenced relative to either a 
different side effect on the same scalar object or a value computation 
using the value of the same scalar object (6.5)."

Why wouldn't the Standard discuss "stored value" or "modification" 
instead of using the looser "side effect"?  5.1.2.3p2:

   "Accessing a volatile object, modifying an object, modifying a file, 
or calling a function that does any of those operations are all side 
effects,12) which are changes in the state of the execution environment. 
Evaluation of an expression in general includes both value computations 
and initiation of side effects. Value computation for an lvalue 
expression includes determining the identity of the designated object."

There is no need for any extra-linguistic side effect, since "accessing 
a volatile object" is a side effect by its own right.  I think examples 
can still be helpful, though.

6.7.3p7:

   "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."

If the last sentence here means that an implementation has license to 
redefine that one or both of a read or a store is _not_ an access to a 
volatile-qualified type, then it cannot abide by the second sentence, 
which involves the semantics of reading and modifying.  If one accepts 
that the final sentence is not allowing for a redefinition of "access," 
then it must be allowing for a definition of what [else] _constitutes_ 
an access, such as:

- A clock tick increments the stored value of a tick-counter
- A read of a usage-counter increments the stored value of the usage-counter
- A read of the value of an object used for obtaining random values 
causes the object's stored value to change to a new random value

"Undefined" by the Standard can obviously be defined by the 
implementation, but need not be, which is why I'd suggest that it's 
undefined.  (The implementation doesn't have to know, document, or be 
consistent about it.)

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#29591

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-12-21 23:52 +0000
Message-ID<kb2sod$13n$1@speranza.aioe.org>
In reply to#29586
Shao Miller <sha0.miller@gmail.com> wrote:

> On 12/21/2012 16:16, Tim Rentsch wrote:
(snip)
>> IMO this conclusion is wrong.  The consequences of volatile access (ie,
>> the extra-linguistic side effects) are outside the domain of 6.5p2,
>> because it is concerned only with program expressions, not other
>> unknown memory changes.  This view is explained in more detail in my
>> response to Ben Bacarisse in this thread.
 
> I read the other response.  And what about if 'x' and "foo counter" are 
> the same scalar?  Regardless of that or any other example, N1570's 
> informative Annex I, point 2 includes:
 
>   "An ??????unordered?????? binary operator (not comma, &&, or ||) contains a 
> side effect to an lvalue in one operand, and a side effect to, or an 
> access to the value of, the identical lvalue in the other operand (6.5)."

This seems to be for expressions like (x++)+(x).

Also, it seems to indicate that access isn't a side affect.
 
> Informative Annex J "Portability issues", J.2 "Undefined behavior", 
> point 1 includes:
 
>   "A side effect on a scalar object is unsequenced relative to either a 
> different side effect on the same scalar object or a value computation 
> using the value of the same scalar object (6.5)."
 
> Why wouldn't the Standard discuss "stored value" or "modification" 
> instead of using the looser "side effect"?  5.1.2.3p2:
 
>   "Accessing a volatile object, modifying an object, modifying a file, 
> or calling a function that does any of those operations are all side 
> effects,12) which are changes in the state of the execution environment. 
> Evaluation of an expression in general includes both value computations 
> and initiation of side effects. Value computation for an lvalue 
> expression includes determining the identity of the designated object."

Is there any indication in the standard on what "side affect" means
for volatile data?  I/O registers have been mentioned in the discussion,
but is that in the standard?

There have been systems with self-incrementing or self-decrementing
memory locations. If one was used for a volatile variable, then
there is an obvious side effect.
 
> There is no need for any extra-linguistic side effect, since "accessing 
> a volatile object" is a side effect by its own right.  I think examples 
> can still be helpful, though.
 
> 6.7.3p7:
 
>   "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."

Sometimes "access" means fetch but not store. I am not so sure
in this case either way.
 
> If the last sentence here means that an implementation has license to 
> redefine that one or both of a read or a store is _not_ an access to a 
> volatile-qualified type, then it cannot abide by the second sentence, 
> which involves the semantics of reading and modifying.  If one accepts 
> that the final sentence is not allowing for a redefinition of "access," 
> then it must be allowing for a definition of what [else] _constitutes_ 
> an access, such as:
 
> - A clock tick increments the stored value of a tick-counter
> - A read of a usage-counter increments the stored value of the usage-counter
> - A read of the value of an object used for obtaining random values 
> causes the object's stored value to change to a new random value

Seems to me that these all have to be implementation dependent
(or implementation defined), in which case the effects and meaning
of "volatile" should also be so defined.
 
> "Undefined" by the Standard can obviously be defined by the 
> implementation, but need not be, which is why I'd suggest that it's 
> undefined.  (The implementation doesn't have to know, document, or be 
> consistent about it.)

-- glen

[toc] | [prev] | [next] | [standalone]


#29593

FromShao Miller <sha0.miller@gmail.com>
Date2012-12-21 19:47 -0500
Message-ID<kb2vua$ai9$1@dont-email.me>
In reply to#29591
On 12/21/2012 18:52, glen herrmannsfeldt wrote:
> Shao Miller <sha0.miller@gmail.com> wrote:
>
>> On 12/21/2012 16:16, Tim Rentsch wrote:
> (snip)
>>> IMO this conclusion is wrong.  The consequences of volatile access (ie,
>>> the extra-linguistic side effects) are outside the domain of 6.5p2,
>>> because it is concerned only with program expressions, not other
>>> unknown memory changes.  This view is explained in more detail in my
>>> response to Ben Bacarisse in this thread.
>
>> I read the other response.  And what about if 'x' and "foo counter" are
>> the same scalar?  Regardless of that or any other example, N1570's
>> informative Annex I, point 2 includes:
>
>>    "An ??????unordered?????? binary operator (not comma, &&, or ||) contains a
>> side effect to an lvalue in one operand, and a side effect to, or an
>> access to the value of, the identical lvalue in the other operand (6.5)."
>
> This seems to be for expressions like (x++)+(x).
>
> Also, it seems to indicate that access isn't a side affect.
>

Down below in 5.1.2.3p2, we see that for volatile-qualified types of 
objects, it really is.  The upthread question about volatile 'x' in 'x + 
x' has been snipped.

>> Informative Annex J "Portability issues", J.2 "Undefined behavior",
>> point 1 includes:
>
>>    "A side effect on a scalar object is unsequenced relative to either a
>> different side effect on the same scalar object or a value computation
>> using the value of the same scalar object (6.5)."
>
>> Why wouldn't the Standard discuss "stored value" or "modification"
>> instead of using the looser "side effect"?  5.1.2.3p2:
>
>>    "Accessing a volatile object, modifying an object, modifying a file,
>> or calling a function that does any of those operations are all side
>> effects,12) which are changes in the state of the execution environment.
>> Evaluation of an expression in general includes both value computations
>> and initiation of side effects. Value computation for an lvalue
>> expression includes determining the identity of the designated object."
>
> Is there any indication in the standard on what "side affect" means
> for volatile data?  I/O registers have been mentioned in the discussion,
> but is that in the standard?
>

Yes.  [Albeit non-normative] Footnote 134 in 6.7.3p7:

   "A volatile declaration may be used to describe an object 
corresponding to a memory-mapped input/output port or an object accessed 
by an asynchronously interrupting function. Actions on objects so 
declared shall not be ‘‘optimized out’’ by an implementation or 
reordered except as permitted by the rules for evaluating expressions."

> There have been systems with self-incrementing or self-decrementing
> memory locations. If one was used for a volatile variable, then
> there is an obvious side effect.
>

I believe that there are _two_ side effects; one by 5.1.2.3p2 and one by 
either "other unknown side effects" or due to an 
"implementation-defined", additional "access".  (Both of these latter 
from 6.7.3p7.)

>> There is no need for any extra-linguistic side effect, since "accessing
>> a volatile object" is a side effect by its own right.  I think examples
>> can still be helpful, though.
>
>> 6.7.3p7:
>
>>    "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."
>
> Sometimes "access" means fetch but not store. I am not so sure
> in this case either way.
>

"Access" is the very first definition under section 3 "Terms, 
definitions, and symbols".  3.1p1:

   "access
〈execution-time action〉 to read or modify the value of an object"

Then 3.1p2 further addresses your query:

   "NOTE 1 Where only one of these two actions is meant, ‘‘read’’ or 
‘‘modify’’ is used."

>> If the last sentence here means that an implementation has license to
>> redefine that one or both of a read or a store is _not_ an access to a
>> volatile-qualified type, then it cannot abide by the second sentence,
>> which involves the semantics of reading and modifying.  If one accepts
>> that the final sentence is not allowing for a redefinition of "access,"
>> then it must be allowing for a definition of what [else] _constitutes_
>> an access, such as:
>
>> - A clock tick increments the stored value of a tick-counter
>> - A read of a usage-counter increments the stored value of the usage-counter
>> - A read of the value of an object used for obtaining random values
>> causes the object's stored value to change to a new random value
>
> Seems to me that these all have to be implementation dependent
> (or implementation defined), in which case the effects and meaning
> of "volatile" should also be so defined.
>

Why?  3.4.1p1:

   "implementation-defined behavior
unspecified behavior where each implementation documents how the choice 
is made"

Once again, 6.7.3p7 includes:

   "An object that has volatile-qualified type may be modified in ways 
unknown to the implementation or have other unknown side effects. ..."

So each of the three examples could belong to either of these two 
categories.  Or, they could be implementation-defined, additional accesses.

>> "Undefined" by the Standard can obviously be defined by the
>> implementation, but need not be, which is why I'd suggest that it's
>> undefined.  (The implementation doesn't have to know, document, or be
>> consistent about it.)
>

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#29602

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-21 22:54 -0800
Message-ID<kfnvcbu4lvm.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29586
Shao Miller <sha0.miller@gmail.com> writes:

> On 12/21/2012 16:16, Tim Rentsch wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>
>>> On 12/20/2012 11:00, Ken Brody wrote:
>>>>
>>>> Condensed version of the discussion so far, in this subthread:
>>>>
>>>> =====
>>>>
>>>> Given:
>>>>
>>>>       extern volatile int x;
>>>>       int i = x + x;
>>>>
>>>> And citing several C&V from different standards regarding the fact
>>>> merely accessing a volatile is a "side effect".
>>>>
>>>> Does the above invoke UB?  (No sequence point between the two "side
>>>> effects" of accessing "x".)
>>>>
>>>> =====
>>>>
>>>> The Standard also requires (5.1.2.3p2) that all side effects be
>>>> "complete" at the next sequence point.
>>>>
>>>> Given that whatever side effect the access of "x" may have is outside
>>>> the control of the abstract machine, I fail to see how the sequence
>>>> point requirement applies to the side effect of accessing a volatile.
>>>>
>>>> Consider, for example, a memory-mapped I/O system, where reading from a
>>>> given address causes the printer to start printing whatever is in its
>>>> buffer.  How can C enforce the "shall be complete" requirement of
>>>> 5.1.2.3p2?  How is "i=x;i+=x;" any better than "i=x+x;"?
>>>>
>>>
>>> Yes, it invokes undefined behaviour.  If a read of 'x' is a side
>>> effect, then two reads of 'x' are two side effects that could conflict
>>> if they occur simultaneously.  That is, since an implementation can
>>> say that a read of 'x' increments a foo counter elsewhere, then two
>>> simultaneous reads can result in two simultaneous increments of the
>>> foo counter, which blows up the computer.
>>
>> IMO this conclusion is wrong.  The consequences of volatile access (ie,
>> the extra-linguistic side effects) are outside the domain of 6.5p2,
>> because it is concerned only with program expressions, not other
>> unknown memory changes.  This view is explained in more detail in my
>> response to Ben Bacarisse in this thread.
>
> I read the other response.   [...snip...]

Then apparently you didn't understand it.

[toc] | [prev] | [next] | [standalone]


#29605

FromShao Miller <sha0.miller@gmail.com>
Date2012-12-22 03:31 -0500
Message-ID<kb3r47$nj5$1@dont-email.me>
In reply to#29602
On 12/22/2012 01:54, Tim Rentsch wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>
>> On 12/21/2012 16:16, Tim Rentsch wrote:
>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>
>>>> On 12/20/2012 11:00, Ken Brody wrote:
>>>>>
>>>>> Condensed version of the discussion so far, in this subthread:
>>>>>
>>>>> =====
>>>>>
>>>>> Given:
>>>>>
>>>>>        extern volatile int x;
>>>>>        int i = x + x;
>>>>>
>>>>> And citing several C&V from different standards regarding the fact
>>>>> merely accessing a volatile is a "side effect".
>>>>>
>>>>> Does the above invoke UB?  (No sequence point between the two "side
>>>>> effects" of accessing "x".)
>>>>>
>>>>> =====
>>>>>
>>>>> The Standard also requires (5.1.2.3p2) that all side effects be
>>>>> "complete" at the next sequence point.
>>>>>
>>>>> Given that whatever side effect the access of "x" may have is outside
>>>>> the control of the abstract machine, I fail to see how the sequence
>>>>> point requirement applies to the side effect of accessing a volatile.
>>>>>
>>>>> Consider, for example, a memory-mapped I/O system, where reading from a
>>>>> given address causes the printer to start printing whatever is in its
>>>>> buffer.  How can C enforce the "shall be complete" requirement of
>>>>> 5.1.2.3p2?  How is "i=x;i+=x;" any better than "i=x+x;"?
>>>>>
>>>>
>>>> Yes, it invokes undefined behaviour.  If a read of 'x' is a side
>>>> effect, then two reads of 'x' are two side effects that could conflict
>>>> if they occur simultaneously.  That is, since an implementation can
>>>> say that a read of 'x' increments a foo counter elsewhere, then two
>>>> simultaneous reads can result in two simultaneous increments of the
>>>> foo counter, which blows up the computer.
>>>
>>> IMO this conclusion is wrong.  The consequences of volatile access (ie,
>>> the extra-linguistic side effects) are outside the domain of 6.5p2,
>>> because it is concerned only with program expressions, not other
>>> unknown memory changes.  This view is explained in more detail in my
>>> response to Ben Bacarisse in this thread.
>>
>> I read the other response.   [...snip...]
>
> Then apparently you didn't understand it.
>

Well in that case, I'd really like to enhance that understanding, if 
possible. :)

On 12/21/2012 16:09, Tim Rentsch wrote:
> Suppose C had a provision for "magic functions".  A magic function
> is declared and defined just the same way that ordinary C functions
> are (perhaps with an additional 'magic' keyword), and are called
> the same way as ordinary functions.  However, outside of the
> language, including both the Standard itself and also any aspects
> known to any implementation, there is a way of setting magic
> functions so that they activate a logic control wire whose purpose
> (and consequences) are unknown as far as the Standard is concerned
> (again including both portable behavior and implementation-defined
> behavior).  This activation takes place whenever a magic function
> is called.  Even though the Standard doesn't know what will happen,
> it wants to guarantee that the associated logic control wires are
> activated, so it stipulates that calling a magic function is always
> required, even if, eg, the function body is empty, and if that is
> known at every point of call.

This seems pretty clear.  It also seems analogous to the semantics of 
'volatile'; helping to ensure that any non-standard side effects are 
correctly "wired," regardless of their existence.

> Under these hypothetical conditions, calling a magic function has,
> at least potentially, the same consequences as undefined behavior
> does.  However, the act of calling a magic function does not give
> an implementation any license to ignore or violate requirements.
> This is true because, even though calling a magic function might
> do something horrible, _it also might not_, and implementations
> must proceed just as they would if nothing bad has happened,
> because as far as they know that could be true.

As in, the computer could melt, but that possibility is entirely outside 
of the scope of C, and we must discuss and behave as though it won't. 
Seems pretty reasonable.  That bit about "license" and "violate 
requirements" is interesting.  One apparent requirement from the 
definitions is that a read or store be considered an access.  If that's 
a mistaken interpretation, so be it.

> It's important to remember what 'undefined behavior' means, which
> is a statement about how implementations may behave.  Calling a
> magic function has unlimited consequences in how an /execution/ may
> behave, but that doesn't eliminate any requirements for how the
> /implementation/ must behave.  Statements in the Standard are
> really about what implementations (ie, mostly compilers) do, not
> about what happens during execution.  Even though calling a magic
> function has potentially unlimited consequences during execution,
> it doesn't change what an implementation is obliged to do to
> conform to the Standard's requirements.  That is the key point.

I remember there was a toy that was a box and a switch.  When you 
flipped the switch, a false hand would come slowly creeping out of the 
box, with a finger aimed at the switch.  At some point it'd flip the 
switch and a release would cause the hand to be instantly retracted back 
into the box.  If this toy was programmed in C, we might hope that the 
implementation was conforming even though the Nth write to the 
"keep_going" volatile scalar was always mysteriously tied to a 
power-loss event.

> To get back to volatile, the consequences of accessing a volatile
> are just the same as calling a hypothetical magic function.  It is
> true that performing a volatile-qualifed access counts as a side
> effect, but not necessarily a side effect on the object being
> accessed.

This would seem to me to be more of a key point than the last one.  If 
one accepts this, then it is easy to agree that there _might_ not be any 
"trouble" with the Standard's discussion of unsequenced side effects on 
the same scalar.

But why not?  Is the suggestion that the wording of N1570's 5.1.2.3p2 
does not match the authors' intentions?

   "Accessing a volatile object, modifying an object, modifying a file, 
or calling a function that does any of those operations are all side 
effects,12) which are changes in the state of the execution environment. 
Evaluation of an expression in general includes both value computations 
and initiation of side effects. Value computation for an lvalue 
expression includes determining the identity of the designated object."

Maybe something more like:

   "Modifying an object, modifying a file, or calling a function that 
does any of those operations are all side effects,12) which are changes 
in the state of the execution environment. In addition, accessing a 
volatile object may cause side effects that may result in 
implementation-defined or undefined behavior, but such side effects are 
either implementation-defined or outside of the scope of this standard. 
Evaluation of an expression in general includes both value computations 
and initiation of side effects. Value computation for an lvalue 
expression includes determining the identity of the designated object."

> The consequences of accessing a volatile object are
> potentially horrible, and as a result something really bad might
> happen, but here again _it also might not_.  Because it is unknown,
> and indeed unknowable, by fiat in the Standard, what the
> consequences of a volatile-qualified access will be, implementations
> must behave just as they would if the accesses in question did
> nothing more than what an ordinary access would do.  Ergo the
> term 'undefined behavior' does not apply.

What about ensuring that all volatile reads (side effects, if 
interpreted literally) enjoy the fantastic new sequencing semantics, 
such as the discussions of side effects having been completed before a 
sequence point?

If a volatile _read_ was not a side effect, but might possibly initiate 
one that we shouldn't worry about, then perhaps given:

   volatile int x;
   x = 13;
   int y = x + x;
   x = 42;

we could actually get away with:

   1. set value of x to 13
   2. side effect for 1
   3. sequence point
   4. read value of x
   5. side effect for 4
   6. read value of x and add the value from 4 to compute initial value 
for y
   7. set value of y
   8. sequence point
   9. side effect that was skipped for 6 (hey, we don't know!)
  10. set value of x to 42
  11. side effect for 10

Now the 9 and 11 might happen simultaneously.  They might have nothing 
to do with the value of the scalar 'x' itself, but they are able to 
collide.  Same potential for collision if a read _is_ always a side 
effect (even if the value of scalar 'x' still isn't influenced by that 
side effect):

   1. set value of x to 13
   2. side effect for 1
   3. sequence point
   4. read value of x
   5. side effect for 4
   6. read value of x
   7. side effect for 6
   8. set value of y
   9. sequence point
  10. set value of x to 42
  11. side effect for 10

Here, 5 and 7 might conflict, except now we can point one finger at the 
programmer and another to the Standard and with raised voice and 
eyebrows low, tell the programmer they're engaging in undefined 
behaviour.  By keeping side effects nice and separate, don't we enjoy a 
little more safety, or else take our chances?

I'm hoping that understanding and agreement are two different things, 
here.  It's a lengthy post, but please do clarify, if and only if you 
have an opportunity. :)  Thank you for your time.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#29630

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-22 09:16 -0800
Message-ID<kfna9t63t2y.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29605
Shao Miller <sha0.miller@gmail.com> writes:

> On 12/22/2012 01:54, Tim Rentsch wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>
>>>> [..snip..snip..snip..]
>>>
>>> I read the other response.   [...snip...]
>>
>> Then apparently you didn't understand it.
>
> Well in that case, I'd really like to enhance that understanding,
> if possible. :)  [snip]

My suggestions are:  read more carefully;  think more deeply;  try
to organize your thoughts more systematically;  and make an effort
in your writing to express ideas more clearly and more concisely.

[toc] | [prev] | [next] | [standalone]


#29684

FromShao Miller <sha0.miller@gmail.com>
Date2012-12-24 04:23 -0500
Message-ID<kb96tp$pon$1@dont-email.me>
In reply to#29630
On 12/22/2012 12:16, Tim Rentsch wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>
>> On 12/22/2012 01:54, Tim Rentsch wrote:
>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>
>>>>> [..snip..snip..snip..]
>>>>
>>>> I read the other response.   [...snip...]
>>>
>>> Then apparently you didn't understand it.
>>
>> Well in that case, I'd really like to enhance that understanding,
>> if possible. :)  [snip]
>
> My suggestions are:  read more carefully;  think more deeply;  try
> to organize your thoughts more systematically;  and make an effort
> in your writing to express ideas more clearly and more concisely.
>

The response immediately above does not appear to be an instance of 
valuable discussion.  A response to the points, instead of the person, 
would be more valuable.

"Read more carefully":

   3.1
   1 access
   〈execution-time action〉 to read or modify the value of an object
   2 NOTE 1 Where only one of these two actions is meant, ‘‘read’’ or 
‘‘modify’’ is used.
   ...

   5.1.2.3 Program execution
   ...
   2 Accessing a volatile object, modifying an object, modifying a file, 
or calling a function that does any of those operations are all side 
effects,12) which are changes in the state of the execution environment. 
Evaluation of an expression in general includes both value computations 
and initiation of side effects. Value computation for an lvalue 
expression includes determining the identity of the designated object.
   ...

An access to a volatile object, not just a modification, is a side 
effect, given just these.  If only a modification of a volatile is 
always to be considered a side effect in all cases, then either 3.1p2 
has missed 5.1.2.3p2, or 5.1.2.3p2 requires further refinement.

   6.7.3 Type qualifiers
   ...
   7 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.
   ...

If you believe that this last sentence means that an implementation has 
license to define that a read of a volatile-qualified scalar's value 
does not constitute a side effect, please say so.  If you believe that 
the last sentence is a refinement of 5.1.2.3p2, please say so.  If you 
mean to support such an argument by noting that such a read might not 
(or does not) result in a change in the state of the execution 
environment (from the perspective of the abstract machine, perhaps), 
please say so.

   6.5 Expressions
   ...
   2 If a side effect on a scalar object is unsequenced relative to 
either a different side effect on the same scalar object or a value 
computation using the value of the same scalar object, the behavior is 
undefined. If there are multiple allowable orderings of the 
subexpressions of an expression, the behavior is undefined if such an 
unsequenced side effect occurs in any of the orderings.84)
   ...

If a read of a volatile scalar is always a side effect, then two reads 
of the same volatile scalar are two side effects.  If two such reads are 
unsequenced, then two such reads are two unsequenced side effects on the 
same scalar object.  If this is the case, the behaviour is undefined. 
If, mysteriously, only one of two such reads is a side effect, the other 
is a value computation of the same scalar object, and the behaviour is 
undefined.  If neither such read is a side effect, then the behaviour is 
not undefined.  If you disagree with this logic, please say so.

   volatile int x = 42;
   int y = x + x;

If the behaviour is always undefined, then we can be careful to avoid it 
and implementations might choose to warn about it.  This seems 
reasonable, to me.  I suspect this is the case.

If the behaviour is always implementation-defined, then we can always 
determine the behaviour by reading the implementation's definition for 
what constitutes a volatile access.  This seems reasonable, to me.  Is 
this what you suggest?

Are there other possibilities?

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#29721

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-27 11:07 -0800
Message-ID<kfnzk0z1fha.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29684
Shao Miller <sha0.miller@gmail.com> writes:

> On 12/22/2012 12:16, Tim Rentsch wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>
>>> On 12/22/2012 01:54, Tim Rentsch wrote:
>>>> Shao Miller <sha0.miller@gmail.com> writes:
>>>>
>>>>>> [..snip..snip..snip..]
>>>>>
>>>>> I read the other response.   [...snip...]
>>>>
>>>> Then apparently you didn't understand it.
>>>
>>> Well in that case, I'd really like to enhance that understanding,
>>> if possible. :)  [snip]
>>
>> My suggestions are:  read more carefully;  think more deeply;  try
>> to organize your thoughts more systematically;  and make an effort
>> in your writing to express ideas more clearly and more concisely.
>
> The response immediately above does not appear to be an instance of
> valuable discussion.  A response to the points, instead of the person,
> would be more valuable.  [snip]

What I was responding to was your statement.  You said you'd like
a better understanding, and I gave some suggestions for what to
do to achieve that.  I'm sorry if my ideas there weren't along
the same lines as your own.  If you're still interested, how
about going back to my long posting in the other subthread and
responding to that by just paraphrasing what I was saying there
to make sure you're understanding my comments.  I think that
would be a good way to continue.

[toc] | [prev] | [next] | [standalone]


#29376

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-17 02:33 -0800
Message-ID<kfna9tdj7cx.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29193
Eric Sosman <esosman@comcast-dot-net.invalid> writes:

> On 12/12/2012 4:13 PM, James Kuyper wrote:
>> On 12/12/2012 04:02 PM, Eric Sosman wrote:
>> ...
>>>       The usual misunderstanding is that the association of
>>> operators with their operands -- "expression tree order" --
>>> dictates evaluation order, which it doesn't.  (Except for
>>> certain special operators like ||, and even then only in
>>> part.)
>>
>> The expression tree does not impose an evaluation order on it's branches
>> at the same level (with the exceptions that you noted), but it does
>> impose a requirement that the operands be evaluated before the
>> expression itself. I believe that this requirement has always been
>> implied by the semantics of each expression, but C2011 has made this
>> requirement explicit for all expression in 6.5p1 and 5.1.2.4p18 (which I
>> just mis-cited in my response to Kenneth as 5.1.2.4p9).
>
>     Although I haven't studied the C11 stuff in detail, I'd
> be surprised (and disappointed!) if in
>
> 	#define WHICH 1
> 	...
> 	int r = WHICH * (x + y) + (1 - WHICH) * (z - x);
>
> ... the Standard required that `z - x' be evaluated at all,
> much less "before" the entire expression.

The statements about evaluation order are not requirements but
part of defining the abstract machine.  In the abstract machine
all expressions are evaluated (subject of course to the semantic
rules about execution flow, sizeof, etc).  The requirement you're
asking about is on program _execution_, for which there is only
one:  that it produce the same results as the semantics described
for the abstract machine would.  There is nothing that says a
program execution has to evaluate any expressions, or even have
something corresponding to an "expression" in its execution
state.  So it's not really a meaningful question.

[toc] | [prev] | [next] | [standalone]


#29369

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-17 02:18 -0800
Message-ID<kfnehipj829.fsf@x-alumni2.alumni.caltech.edu>
In reply to#29183
James Kuyper <jameskuyper@verizon.net> writes:

> On 12/12/2012 04:02 PM, Eric Sosman wrote:
> ...
>>      The usual misunderstanding is that the association of
>> operators with their operands -- "expression tree order" --
>> dictates evaluation order, which it doesn't.  (Except for
>> certain special operators like ||, and even then only in
>> part.)
>
> The expression tree does not impose an evaluation order on it's
> branches at the same level (with the exceptions that you noted),
> but it does impose a requirement that the operands be evaluated
> before the expression itself.  I believe that this requirement has
> always been implied by the semantics of each expression, but C2011
> has made this requirement explicit for all expression in 6.5p1 and
> 5.1.2.4p18 (which I just mis-cited in my response to Kenneth as
> 5.1.2.4p9).

The phrasing here is a little funny.  The rules for evaluation
order are not a requirement but rather (part of) a definition
of the semantics of the abstract machine.  That definition has
always expressed these constraints on evaluation order;  the
description in C11 simply expresses them more clearly.

[toc] | [prev] | [next] | [standalone]


#29149

FromNoob <root@127.0.0.1>
Date2012-12-11 11:36 +0100
Message-ID<ka725t$4qj$1@dont-email.me>
In reply to#29144
Edward A. Falk wrote:

> I assume that *(a+(i-j)) would be ok?

Please correct me if I am wrong,

*(a+(i-j)) is strictly equivalent to a[i-j]

(I find the latter clearer.)

[toc] | [prev] | [next] | [standalone]


#29158

From"christian.bau" <christian.bau@cbau.wanadoo.co.uk>
Date2012-12-11 10:00 -0800
Message-ID<6e90fa44-2732-4cee-a009-71c104eabba1@a15g2000vbf.googlegroups.com>
In reply to#29149
On Dec 11, 10:36 am, Noob <r...@127.0.0.1> wrote:
> Edward A. Falk wrote:
> > I assume that *(a+(i-j)) would be ok?
>
> Please correct me if I am wrong,
>
> *(a+(i-j)) is strictly equivalent to a[i-j]
>
> (I find the latter clearer.)

Yes, it's the same. But there are also cases where * (a + i - j) would
be fine and * (a + (i - j)) or a [i - j] wouldn't: If you have 64 bit
pointers and 32 bit ints, then i - j might overflow, while a + i - j
could be correct.

[toc] | [prev] | [next] | [standalone]


#29372

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-12-17 12:11 +0200
Message-ID<87y5gxj8df.fsf@bazspaz.fatphil.org>
In reply to#29158
"christian.bau" <christian.bau@cbau.wanadoo.co.uk> writes:
> On Dec 11, 10:36 am, Noob <r...@127.0.0.1> wrote:
> > Edward A. Falk wrote:
> > > I assume that *(a+(i-j)) would be ok?
> >
> > Please correct me if I am wrong,
> >
> > *(a+(i-j)) is strictly equivalent to a[i-j]
> >
> > (I find the latter clearer.)
> 
> Yes, it's the same. But there are also cases where * (a + i - j) would
> be fine and * (a + (i - j)) or a [i - j] wouldn't: If you have 64 bit
> pointers and 32 bit ints, then i - j might overflow, while a + i - j
> could be correct.

i and j are not int but size_t. What do you mean by "overflow" in that context?
Can you come up with a concrete example of failure which doesn't have UB 
in the "correct" version?

Phil
-- 
I'm not saying that google groups censors my posts, but there's a strong link
between me saying "google groups sucks" in articles, and them disappearing.

Oh - I guess I might be saying that google groups censors my posts.

[toc] | [prev] | [next] | [standalone]


#29161

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2012-12-11 15:27 -0500
Message-ID<ka8501$545$1@dont-email.me>
In reply to#29144
On 12/10/2012 7:46 PM, Edward A. Falk wrote:
> In article <ka59e6$mq7$1@dont-email.me>,
> Eric Sosman  <esosman@comcast-dot-net.invalid> wrote:
>>
>>      A colleague who did some work on IBM's AS/400 (they've
>> changed the name; I forget the new one) told me that simply
>> trying to calculate an out-of-range pointer yielded a null
>> pointer as a result.
>
> Heh; learn something new every day.  I never would have guessed
> that there was an actual architecture that would blow up with
> this construct.
>
> I assume that *(a+(i-j)) would be ok?

     Assuming `i-j' in range, yes.

     More on my colleague's tale: The code maintained a buffer
in which items of various sizes accumulated, and which drained
to disk when it got too full or too old.  To decide whether a
newly-offered item would fit, the code did something like

	itemEndPtr = nextBufferSpacePtr + itemSize;
	if (itemEndPtr < bufferStart + bufferSize) ...

This worked as intended on all the other target systems, but
failed on AS/400.  I suspect the failure had something to do
with the fact that the buffer was in a shared memory area, so
stepping off the end also meant stepping outside of mapped
address space; the problem might not have shown up with the
`auto' array in your example.

     Still, perhaps a salutary lesson for the folks who still
believe "All the world's a VAX^H^H^Hx86^H^H^Hx64^H^H^H..."

-- 
Eric Sosman
esosman@comcast-dot-net.invalid

[toc] | [prev] | [next] | [standalone]


#29162

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-12-11 21:09 +0000
Message-ID<ka87dh$abe$1@speranza.aioe.org>
In reply to#29161
Eric Sosman <esosman@comcast-dot-net.invalid> wrote:

(previous snip on pointer offsets)

>>>      A colleague who did some work on IBM's AS/400 (they've
>>> changed the name; I forget the new one) told me that simply
>>> trying to calculate an out-of-range pointer yielded a null
>>> pointer as a result.

>> Heh; learn something new every day.  I never would have guessed
>> that there was an actual architecture that would blow up with
>> this construct.

>> I assume that *(a+(i-j)) would be ok?
 
>     Assuming `i-j' in range, yes.
 
>     More on my colleague's tale: The code maintained a buffer
> in which items of various sizes accumulated, and which drained
> to disk when it got too full or too old.  To decide whether a
> newly-offered item would fit, the code did something like
 
>        itemEndPtr = nextBufferSpacePtr + itemSize;
>        if (itemEndPtr < bufferStart + bufferSize) ...

Might fail in x86 (especially the 80286) in huge model.

You can't load arbitrary data into segment selector registers
in protected mode x86. In large mode, though, any offset isn't
tested until an actual access is attempted. (The offset is in
an ordinary register, such as AX.) 

In huge model, the system allocates a series of segments,
such that the one can address through them in order.

Still, I believe that the compilers are careful not to load
a segment selector until needed to actually access something,
maybe partly to allow such faulty C code.
 
> This worked as intended on all the other target systems, but
> failed on AS/400.  I suspect the failure had something to do
> with the fact that the buffer was in a shared memory area, so
> stepping off the end also meant stepping outside of mapped
> address space; the problem might not have shown up with the
> `auto' array in your example.

I believe that could happen with protected mode x86, too.
 
>     Still, perhaps a salutary lesson for the folks who still
> believe "All the world's a VAX^H^H^Hx86^H^H^Hx64^H^H^H..."

In the 80286 days, I had OS/2 1.0 and then 1.2 running, when
just about everyone else was running MS-DOS. Instead of using
malloc(), I would directly allocate segments from OS/2 of exactly
the needed length. The hardware will then interrupt for an access,
even read, either before or just after the end of the allocated
space. (Unless the register wraps, and it is back into the 
allocated space again.) 

As usual in C, a 2D array was allocated as an array of pointers,
each pointing to its own OS/2 allocated segment. 

Fortunately, the C compilers were always good at not using segment
selector registers when copying pointers that might not point to
anything.

I don't know AS/400 that well, but there have been systems that relied
on the compiler to generate the appropriate code, instead of run-time
memory protection. I believe some Burroughs ALGOL systems worked that
way. (Maybe still do.)

As far as I know, they never had a C compiler, but if one did it might
also have problems with out of range pointers.

-- glen

[toc] | [prev] | [next] | [standalone]


#29175

FromKen Brody <kenbrody@spamcop.net>
Date2012-12-12 14:30 -0500
Message-ID<kaam0m$6cd$1@dont-email.me>
In reply to#29144
On 12/10/2012 7:46 PM, Edward A. Falk wrote:
> In article <ka59e6$mq7$1@dont-email.me>,
> Eric Sosman  <esosman@comcast-dot-net.invalid> wrote:
>>
>>      A colleague who did some work on IBM's AS/400 (they've
>> changed the name; I forget the new one) told me that simply
>> trying to calculate an out-of-range pointer yielded a null
>> pointer as a result.
>
> Heh; learn something new every day.  I never would have guessed
> that there was an actual architecture that would blow up with
> this construct.
>
> I assume that *(a+(i-j)) would be ok?

No.  There is no requirement that the value of "i-j" be calculated prior to 
adding it to "a".  (Check the numerous threads here involving using 
parentheses to "fix" UB in things involving such constructs as "i + (i++)".) 
  Operator precedence only guarantees how the expression is to be 
interpreted, not the actual order of evaluation.

[toc] | [prev] | [next] | [standalone]


#29177

FromKeith Thompson <kst-u@mib.org>
Date2012-12-12 11:42 -0800
Message-ID<lnvcc7kqfc.fsf@nuthaus.mib.org>
In reply to#29175
Ken Brody <kenbrody@spamcop.net> writes:
> On 12/10/2012 7:46 PM, Edward A. Falk wrote:
>> In article <ka59e6$mq7$1@dont-email.me>,
>> Eric Sosman  <esosman@comcast-dot-net.invalid> wrote:
>>>
>>>      A colleague who did some work on IBM's AS/400 (they've
>>> changed the name; I forget the new one) told me that simply
>>> trying to calculate an out-of-range pointer yielded a null
>>> pointer as a result.
>>
>> Heh; learn something new every day.  I never would have guessed
>> that there was an actual architecture that would blow up with
>> this construct.
>>
>> I assume that *(a+(i-j)) would be ok?
>
> No.  There is no requirement that the value of "i-j" be calculated prior to 
> adding it to "a".  (Check the numerous threads here involving using 
> parentheses to "fix" UB in things involving such constructs as "i + (i++)".) 
>   Operator precedence only guarantees how the expression is to be 
> interpreted, not the actual order of evaluation.

True, but the expression `a+(i-j)` is evaluated *in the abstract
machine* by subtracting j from i and then adding the result to a.
A compiler is free to evaluate it by computing a+i and then
subtracting j from the result *only* if it can guarantee that the
result is the same, or if the canonical order has undefined behavior.

`INT_MAX + (1 - 1)` has well defined behavior.
`INT_MAX + 1 - 1` does not.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#29189

FromKen Brody <kenbrody@spamcop.net>
Date2012-12-12 17:12 -0500
Message-ID<kaavgr$7ep$1@dont-email.me>
In reply to#29175
On 12/12/2012 2:30 PM, Ken Brody wrote:
> On 12/10/2012 7:46 PM, Edward A. Falk wrote:
>> In article <ka59e6$mq7$1@dont-email.me>,
>> Eric Sosman  <esosman@comcast-dot-net.invalid> wrote:
>>>
>>>      A colleague who did some work on IBM's AS/400 (they've
>>> changed the name; I forget the new one) told me that simply
>>> trying to calculate an out-of-range pointer yielded a null
>>> pointer as a result.
>>
>> Heh; learn something new every day.  I never would have guessed
>> that there was an actual architecture that would blow up with
>> this construct.
>>
>> I assume that *(a+(i-j)) would be ok?
>
> No.  There is no requirement that the value of "i-j" be calculated prior to
> adding it to "a".  (Check the numerous threads here involving using
> parentheses to "fix" UB in things involving such constructs as "i + (i++)".)
>   Operator precedence only guarantees how the expression is to be
> interpreted, not the actual order of evaluation.

As noted in the replies to my post, I stand corrected.  Because of the 
"as-if" rule, if evaluating "i-j" first would not cause an overflow in 
"a+(i-j)", then the compiler must guarantee that any rearranging of the code 
will give an identical result, even if an overflow does occur.

[toc] | [prev] | [next] | [standalone]


Page 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web