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


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

Pointers and Sequence Point

Started byarnuld <sunrise@invalid.address>
First post2011-05-02 11:38 +0000
Last post2011-05-03 08:01 -0700
Articles 14 — 12 participants

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


Contents

  Pointers and Sequence Point arnuld <sunrise@invalid.address> - 2011-05-02 11:38 +0000
    Re: Pointers and Sequence Point James Kuyper <jameskuyper@verizon.net> - 2011-05-02 08:23 -0400
    Re: Pointers and Sequence Point Martin Ambuhl <mambuhl@earthlink.net> - 2011-05-02 09:58 -0400
      Re: Pointers and Sequence Point Chad <cdalten@gmail.com> - 2011-05-02 09:36 -0700
        Re: Pointers and Sequence Point Angel <angel+news@spamcop.net> - 2011-05-02 17:21 +0000
        Re: Pointers and Sequence Point James Kuyper <jameskuyper@verizon.net> - 2011-05-02 23:20 -0400
          Re: Pointers and Sequence Point Keith Thompson <kst-u@mib.org> - 2011-05-02 23:26 -0700
            Re: Pointers and Sequence Point James Kuyper <jameskuyper@verizon.net> - 2011-05-03 05:33 -0400
      Re: Pointers and Sequence Point Kenneth Brody <kenbrody@spamcop.net> - 2011-05-02 13:35 -0400
        Re: Pointers and Sequence Point Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-05-03 17:45 +0300
    Re: Pointers and Sequence Point John Bode <jfbode1029@gmail.com> - 2011-05-02 10:17 -0700
    Re: Pointers and Sequence Point Tim Rentsch <txr@alumni.caltech.edu> - 2011-05-02 10:31 -0700
    Re: Pointers and Sequence Point "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-05-02 20:55 -0400
      Re: Pointers and Sequence Point David Resnick <lndresnick@gmail.com> - 2011-05-03 08:01 -0700

#3125 — Pointers and Sequence Point

Fromarnuld <sunrise@invalid.address>
Date2011-05-02 11:38 +0000
SubjectPointers and Sequence Point
Message-ID<4dbe97cd$0$311$14726298@news.sunsite.dk>
I have this program which is causing confusion to me. I am told that last 
printf() of main() will always print "Second", not "First". I think line:

 x = myAlloc(x);

is UB. My colleague is disagreeing on this while I was saying that its UB 
because there is no sequence point here. It is just like using this line:

 i = i++;

But he says that sequence point will not affect the pointers and hence 
this is perfectly valid ANSI C program. I am confused on this:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { SIZE_LIMIT = 10 };

char* myAlloc(char* c);

int main(void)
{
  char* x = malloc(SIZE_LIMIT * sizeof *x);
  if(NULL == x)
    {
      printf("Out of Memory\n");
      return EXIT_FAILURE;
    }

  strcpy(x, "First");
  printf("x = %s\n", x);
  x = myAlloc(x);
  printf("x = %s\n", x);
      
  return 0;
}


char* myAlloc(char* c)
{
  c = malloc(SIZE_LIMIT * sizeof *c);
  if(NULL == c)
    {
      printf("Out of Memory\n");
      return NULL;
    }
  else
    {
      strcpy(c, "Second");
    }

  return c;
}


================= OUTPUT ====================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra ptrtest.c 
[arnuld@dune programs]$ ./a.out 
x = First
x = Second
[arnuld@dune programs]$ 





-- 
www.lispmachine.wordpress.com
find my email-ID @above blog

[toc] | [next] | [standalone]


#3126

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-02 08:23 -0400
Message-ID<ipm7ot$ocm$1@dont-email.me>
In reply to#3125
On 05/02/2011 07:38 AM, arnuld wrote:
> I have this program which is causing confusion to me. I am told that last 
> printf() of main() will always print "Second", not "First". I think line:
> 
>  x = myAlloc(x);
> 
> is UB. My colleague is disagreeing on this while I was saying that its UB 
> because there is no sequence point here. It is just like using this line:
> 
>  i = i++;

No, it's not. 6.5p2 contains two separate "shalls" that apply between
consecutive sequence points. "i=i++" violates the first one, against
modifying the value of an object twice. Your example modifies the value
of x only once. I presume, therefore, that you're actually worried about
the second one, against reading the value for any purpose other than to
determine what the new value is.

> But he says that sequence point will not affect the pointers and hence 
> this is perfectly valid ANSI C program. I am confused on this:

There is no special exemption of pointers from the rules involving
multiple modifications with no intervening sequence points. "x=x++"
would be just as thoroughly undefined as "i = i++". It's just that
there's a whole lot more relevant sequence points involved in the
evaluation of "x = myAlloc(x)" than you're taking into consideration.

> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> 
> enum { SIZE_LIMIT = 10 };
> 
> char* myAlloc(char* c);
> 
> int main(void)
> {
>   char* x = malloc(SIZE_LIMIT * sizeof *x);
>   if(NULL == x)
>     {
>       printf("Out of Memory\n");
>       return EXIT_FAILURE;
>     }
> 
>   strcpy(x, "First");
>   printf("x = %s\n", x);
>   x = myAlloc(x);

There's a sequence point separating evaluation of 'x' as an argument to
myAlloc() from the call to myAlloc() (6.5.2.2p10).

>   printf("x = %s\n", x);
>       
>   return 0;
> }
> 
> 
> char* myAlloc(char* c)
> {
>   c = malloc(SIZE_LIMIT * sizeof *c);

There's a sequence point separating the multiplication from the call to
malloc(), another just before malloc() returns (7.1.4p3), a third at the
end of the full expression (6.8p4).


>   if(NULL == c)

There's a sequence point at the end of the full expression.

>     {
>       printf("Out of Memory\n");
>       return NULL;
>     }
>   else
>     {
>       strcpy(c, "Second");

There's a sequence point separating the evaluation of the arguments from
the call to strcpy(), a second just before strcpy() returns, and a third
at the end of the full expression.

>     }
> 
>   return c;

There's a sequence point at the end of the full expression.

> }

I count a total of 9 sequence points separating the reading of the value
of x from its modification. One is all that's needed to avoid violating
6.5p2.

-- 
James Kuyper

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


#3127

FromMartin Ambuhl <mambuhl@earthlink.net>
Date2011-05-02 09:58 -0400
Message-ID<ipmdaj$8dk$1@dont-email.me>
In reply to#3125
On 5/2/2011 7:38 AM, arnuld wrote:
> I have this program which is causing confusion to me. I am told that last
> printf() of main() will always print "Second", not "First". I think line:
>
>   x = myAlloc(x);

While it is possible to write evil code in which myAlloc could modify x, 
in C myAlloc receives a copy of the value of x and has no clue where x 
is or how to modify it.  There are not two or more instances of 
modifying x between sequence points.

> is UB. My colleague is disagreeing on this while I was saying that its UB
> because there is no sequence point here. It is just like using this line:
>
>   i = i++;

Now there _are_ two instances of modifying i between sequence points.

Do you see the difference?

> But he says that sequence point will not affect the pointers

"pointers" are not relevant.

> and hence
> this is perfectly valid ANSI C program. I am confused on this:

Your program has other problems, but none related to the question you 
raised.

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


#3130

FromChad <cdalten@gmail.com>
Date2011-05-02 09:36 -0700
Message-ID<77ea7b06-dc58-48b0-bd17-4797d4150058@22g2000prx.googlegroups.com>
In reply to#3127
On May 2, 6:58 am, Martin Ambuhl <mamb...@earthlink.net> wrote:
> On 5/2/2011 7:38 AM, arnuld wrote:
>
> > I have this program which is causing confusion to me. I am told that last
> > printf() of main() will always print "Second", not "First". I think line:
>
> >   x = myAlloc(x);
>
> While it is possible to write evil code in which myAlloc could modify x,
> in C myAlloc receives a copy of the value of x and has no clue where x
> is or how to modify it.  There are not two or more instances of
> modifying x between sequence points.
>

What is the scope of 'x' in myAlloc(x)? Is confined to myAlloc()?

Chad

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


#3133

FromAngel <angel+news@spamcop.net>
Date2011-05-02 17:21 +0000
Message-ID<slrnirtpvv.cu9.angel+news@pearlgates.net>
In reply to#3130
On 2011-05-02, Chad <cdalten@gmail.com> wrote:
> On May 2, 6:58?am, Martin Ambuhl <mamb...@earthlink.net> wrote:
>> On 5/2/2011 7:38 AM, arnuld wrote:
>>
>> > I have this program which is causing confusion to me. I am told that last
>> > printf() of main() will always print "Second", not "First". I think line:
>>
>> > ? x = myAlloc(x);
>>
>> While it is possible to write evil code in which myAlloc could modify x,
>> in C myAlloc receives a copy of the value of x and has no clue where x
>> is or how to modify it. ?There are not two or more instances of
>> modifying x between sequence points.
>>
>
> What is the scope of 'x' in myAlloc(x)? Is confined to myAlloc()?

Assuming that myAlloc() is a function and not a macro, yes. Function
parameters act as local variables within the function block and anything
done to them within that block does not affect anything outside.

The exception to this is of course if x is a pointer, then it is
possible from within the function to modify the data that x points to.


-- 
The perfected state of a spam server is a smoking crater.
- The Crater Corollary to Rule #4

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


#3155

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-02 23:20 -0400
Message-ID<ipnsam$bv2$1@dont-email.me>
In reply to#3130
On 05/02/2011 12:36 PM, Chad wrote:
> On May 2, 6:58�am, Martin Ambuhl <mamb...@earthlink.net> wrote:
>> On 5/2/2011 7:38 AM, arnuld wrote:
>>
>>> I have this program which is causing confusion to me. I am told that last
>>> printf() of main() will always print "Second", not "First". I think line:
>>
>>> � x = myAlloc(x);
>>
>> While it is possible to write evil code in which myAlloc could modify x,
>> in C myAlloc receives a copy of the value of x and has no clue where x
>> is or how to modify it. �There are not two or more instances of
>> modifying x between sequence points.
>>
> 
> What is the scope of 'x' in myAlloc(x)? Is confined to myAlloc()?

The scope of 'x' starts at the declaration of 'x' on the first line of
main(), and is restricted to the body of main(). It goes out of scope
throughout the execution of myAlloc(). It comes back into scope after
that function returns. It's scope ends when main() returns.

-- 
James Kuyper

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


#3158

FromKeith Thompson <kst-u@mib.org>
Date2011-05-02 23:26 -0700
Message-ID<lnei4guwog.fsf@nuthaus.mib.org>
In reply to#3155
James Kuyper <jameskuyper@verizon.net> writes:
> On 05/02/2011 12:36 PM, Chad wrote:
>> On May 2, 6:58�am, Martin Ambuhl <mamb...@earthlink.net> wrote:
>>> On 5/2/2011 7:38 AM, arnuld wrote:
>>>
>>>> I have this program which is causing confusion to me. I am told that last
>>>> printf() of main() will always print "Second", not "First". I think line:
>>>
>>>> � x = myAlloc(x);
>>>
>>> While it is possible to write evil code in which myAlloc could modify x,
>>> in C myAlloc receives a copy of the value of x and has no clue where x
>>> is or how to modify it. �There are not two or more instances of
>>> modifying x between sequence points.
>>>
>> 
>> What is the scope of 'x' in myAlloc(x)? Is confined to myAlloc()?
>
> The scope of 'x' starts at the declaration of 'x' on the first line of
> main(), and is restricted to the body of main(). It goes out of scope
> throughout the execution of myAlloc(). It comes back into scope after
> that function returns. It's scope ends when main() returns.

Your wording  seems to imply that 'x' goes into and out of scope
during execution.  In fact, an entity's scope is a region of
program text.  C99 6.2.1p2.

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

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


#3166

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-03 05:33 -0400
Message-ID<ipoi5k$lht$1@dont-email.me>
In reply to#3158
On 05/03/2011 02:26 AM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
>> On 05/02/2011 12:36 PM, Chad wrote:
>>> On May 2, 6:58�am, Martin Ambuhl <mamb...@earthlink.net> wrote:
>>>> On 5/2/2011 7:38 AM, arnuld wrote:
>>>>
>>>>> I have this program which is causing confusion to me. I am told that last
>>>>> printf() of main() will always print "Second", not "First". I think line:
>>>>
>>>>> � x = myAlloc(x);
>>>>
>>>> While it is possible to write evil code in which myAlloc could modify x,
>>>> in C myAlloc receives a copy of the value of x and has no clue where x
>>>> is or how to modify it. �There are not two or more instances of
>>>> modifying x between sequence points.
>>>>
>>>
>>> What is the scope of 'x' in myAlloc(x)? Is confined to myAlloc()?
>>
>> The scope of 'x' starts at the declaration of 'x' on the first line of
>> main(), and is restricted to the body of main(). It goes out of scope
>> throughout the execution of myAlloc(). It comes back into scope after
>> that function returns. It's scope ends when main() returns.
> 
> Your wording  seems to imply that 'x' goes into and out of scope
> during execution.  In fact, an entity's scope is a region of
> program text.  C99 6.2.1p2.

As the program executes, it executes code corresponding to those
different regions of text, and that's what I was trying to talk about.
However, that correspondence gets complicated to talk about accurately,
especially after optimization. I should really have emphasized that
scope is a compile-time concept, not a run-time one.

The key point is that that all of the operations that might, in some
other context, be problematic, are performed on a variable named 'c',
whose scope is restricted to myAlloc(), that happens to be initialized
with the value of 'x' at the time myAlloc() is called. As a result,
they're not at all problematic.
-- 
James Kuyper

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


#3135

FromKenneth Brody <kenbrody@spamcop.net>
Date2011-05-02 13:35 -0400
Message-ID<rdCdnW-tt8vIdiPQnZ2dnUVZ_vKdnZ2d@bestweb.net>
In reply to#3127
On 5/2/2011 9:58 AM, Martin Ambuhl wrote:
> On 5/2/2011 7:38 AM, arnuld wrote:
>> I have this program which is causing confusion to me. I am told that last
>> printf() of main() will always print "Second", not "First". I think line:
>>
>> x = myAlloc(x);
>
> While it is possible to write evil code in which myAlloc could modify x, in
> C myAlloc receives a copy of the value of x and has no clue where x is or
> how to modify it. There are not two or more instances of modifying x between
> sequence points.

But, unless I'm badly mistaken (and I know I'll be told so if I am), the 
call to and a return from a function are sequence points.  Therefore, as 
long as myAlloc() is a function and not a macro, even this does not invoke UB:

     x = myAlloc(x++);

>> is UB. My colleague is disagreeing on this while I was saying that its UB
>> because there is no sequence point here. It is just like using this line:

The function call is a sequence point.

[...]

-- 
Kenneth Brody

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


#3178

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-05-03 17:45 +0300
Message-ID<8739kvyh9x.fsf@bazspaz.fatphil.org>
In reply to#3135
Kenneth Brody <kenbrody@spamcop.net> writes:

> On 5/2/2011 9:58 AM, Martin Ambuhl wrote:
> > On 5/2/2011 7:38 AM, arnuld wrote:
> >> I have this program which is causing confusion to me. I am told that last
> >> printf() of main() will always print "Second", not "First". I think line:
> >>
> >> x = myAlloc(x);
> >
> > While it is possible to write evil code in which myAlloc could modify x, in
> > C myAlloc receives a copy of the value of x and has no clue where x is or
> > how to modify it. There are not two or more instances of modifying x between
> > sequence points.
> 
> But, unless I'm badly mistaken (and I know I'll be told so if I am),
> the call to and a return from a function are sequence points.
> Therefore, as long as myAlloc() is a function and not a macro, even
> this does not invoke UB:
> 
>      x = myAlloc(x++);
> 
> >> is UB. My colleague is disagreeing on this while I was saying that its UB
> >> because there is no sequence point here. It is just like using this line:
> 
> The function call is a sequence point.

At least 2. One between the evaluation of the parameters and the call, and 
one at the return of the function.

Phil
-- 
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon

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


#3131

FromJohn Bode <jfbode1029@gmail.com>
Date2011-05-02 10:17 -0700
Message-ID<0ab26965-1a9b-48f4-adb5-8985164b9eca@w21g2000yqm.googlegroups.com>
In reply to#3125
On May 2, 6:38 am, arnuld <sunr...@invalid.address> wrote:
> I have this program which is causing confusion to me. I am told that last
> printf() of main() will always print "Second", not "First". I think line:
>
>  x = myAlloc(x);
>
> is UB.

*Only* if myAlloc is a macro that expands to something like "x++" or
similar.  If myAlloc is a function call, then that's not UB at all for
two reasons:

1.  Evaluating "myAlloc(x)" does not modify "x": even if "myAlloc"
writes to its argument, that argument is a physically distinct object
in memory from "x";

2.  There is *at least one* intervening sequence point before the
assignment to "x" between the time the function argument is evaluated
and the function itself is called, not to mention any sequence points
in the function itself.

> My colleague is disagreeing on this while I was saying that its UB
> because there is no sequence point here. It is just like using this line:
>
>  i = i++;
>

Your colleague is correct.

> But he says that sequence point will not affect the pointers

But for the wrong reason, unless he misspoke or you misheard.

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


#3134

FromTim Rentsch <txr@alumni.caltech.edu>
Date2011-05-02 10:31 -0700
Message-ID<kfnwri9vwjt.fsf@x-alumni2.alumni.caltech.edu>
In reply to#3125
arnuld <sunrise@invalid.address> writes:

> I have this program which is causing confusion to me. I am told that last 
> printf() of main() will always print "Second", not "First". I think line:
>
>  x = myAlloc(x);
>
> is UB. [snip elaboration]

If x is a variable and myAlloc(x) is a function call (ie, and
neither x nor myAlloc() is a macro), there is _no way_ this
assignment statement can be undefined behavior (assuming of
course that calling myAlloc() doesn't wander into UB-land just by
itself).

That result holds no matter whether x is of pointer type
or not.

Perhaps you were thinking of a different example?  What's
the smallest, simplest example program that demonstrates
what you think the problem is?

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


#3152

From"Morris Keesan" <mkeesan@post.harvard.edu>
Date2011-05-02 20:55 -0400
Message-ID<op.vuvrjgbl5qv6o3@toshiba-laptop>
In reply to#3125
On Mon, 02 May 2011 07:38:53 -0400, arnuld <sunrise@invalid.address> wrote:

...
>   x = myAlloc(x);

> char* myAlloc(char* c)
> {
>   c = malloc(SIZE_LIMIT * sizeof *c);
...
>   return c;
> }

As has been pointed out, there's no way that myAlloc can possibly do
anything to the value of x.  Perhaps what you were thinking of is the
possibility of undefined behavior in

x = myAlloc(&x);
...
char * myAlloc(char **c)
{
    *c = malloc(SIZE_LIMIT);
    etc.

but there's no undefined behavior here, either, because the function call
inserts multiple sequence points before the assignment to x.
-- 
Morris Keesan -- mkeesan@post.harvard.edu

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


#3180

FromDavid Resnick <lndresnick@gmail.com>
Date2011-05-03 08:01 -0700
Message-ID<17521d69-22bb-46dd-b8ee-e5d790a94f39@h36g2000vbj.googlegroups.com>
In reply to#3152
On May 2, 8:55 pm, "Morris Keesan" <mkee...@post.harvard.edu> wrote:
> On Mon, 02 May 2011 07:38:53 -0400, arnuld <sunr...@invalid.address> wrote:
>
> ...
>
>
>
> >   x = myAlloc(x);
> > char* myAlloc(char* c)
> > {
> >   c = malloc(SIZE_LIMIT * sizeof *c);
> ...
> >   return c;
> > }
>
> As has been pointed out, there's no way that myAlloc can possibly do
> anything to the value of x.  Perhaps what you were thinking of is the
> possibility of undefined behavior in
>
> x = myAlloc(&x);
> ...
> char * myAlloc(char **c)
> {
>     *c = malloc(SIZE_LIMIT);
>     etc.
>
> but there's no undefined behavior here, either, because the function call
> inserts multiple sequence points before the assignment to x.
> --
> Morris Keesan -- mkee...@post.harvard.edu

A more contrived version which has a problem is this:

#include <string.h>
#include <stdlib.h>

typedef struct foo
{
    struct foo *next;
} foo;

struct foo *badness(foo** ouch)
{
    *ouch = realloc(*ouch, 1000);
    return *ouch;
}

int main(void)
{
    struct foo *pFoo = malloc(sizeof *pFoo);
    pFoo->next = badness(&pFoo);
    return 0;
}

Once had bogus code that did something like that with a static
variable, alas.  Worked with older version of gcc, as it figured out
LHS after the function call.  Newer version evaluated LHS before
function call.  UB is like that sometimes...

-David

[toc] | [prev] | [standalone]


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


csiph-web