public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Re: problem in C++ pointer
@ 2000-03-17  9:48 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-17  9:48 UTC (permalink / raw)
  To: stern, swe sd; +Cc: cygwin

>From: James Stern <jsternitg@yahoo.com>
>> "sequence point" is not in the index..
>
>It is in my copy.  Maybe you're looking at a draft?  "point" is a
>subtopic under "sequence."

Darn, I had two copies of the standard, one definitely not final, one said
it should be final it just hadn't been voted on,  and it looks like I might
be using the "wrong" one, dated only April 1995, can't find the other, and
the index is definitely different.

Thanks for the clarifications.

 - Jay

-----Original Message-----
From: James Stern <jsternitg@yahoo.com>
To: Jay Krell <jay.krell@cornell.edu>; swe sd <ccwork@hotmail.com>
Cc: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
Date: Thursday, March 16, 2000 8:39 AM
Subject: Re: problem in C++ pointer


[]


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: problem in C++ pointer
@ 2000-03-17 13:26 Heribert Dahms
  0 siblings, 0 replies; 12+ messages in thread
From: Heribert Dahms @ 2000-03-17 13:26 UTC (permalink / raw)
  To: 'Jay Krell', stern, swe sd; +Cc: cygwin

Wow, that must be a small standard if you overlooked it under the mouse
pad!
Do you have an URL, please?

Bye, Heribert (heribert_dahms@icon-gmbh.de)

> -----Original Message-----
> From:	Jay Krell [SMTP:jay.krell@cornell.edu]
> Sent:	Friday, March 17, 2000 22:18
> To:	stern@itginc.com; swe sd
> Cc:	cygwin@sourceware.cygnus.com
> Subject:	Re: problem in C++ pointer
> Importance:	Low
> 
> Damn that was dumb. The newer one was under the mouse pad.. "FDIS",
> 1998..
> It does have point, sequence in the index..
> 
> -----Original Message-----
> >it looks like I might be using the "wrong" one, dated only April
> 1995,
> can't find the other
> >[]
> 
> 
> 
> --
> Want to unsubscribe from this list?
> Send a message to cygwin-unsubscribe@sourceware.cygnus.com

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-17 13:15 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-17 13:15 UTC (permalink / raw)
  To: stern, swe sd; +Cc: cygwin

Damn that was dumb. The newer one was under the mouse pad.. "FDIS", 1998..
It does have point, sequence in the index..

-----Original Message-----
>it looks like I might be using the "wrong" one, dated only April 1995,
can't find the other
>[]



--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-16  8:39 James Stern
  0 siblings, 0 replies; 12+ messages in thread
From: James Stern @ 2000-03-16  8:39 UTC (permalink / raw)
  To: Jay Krell, swe sd; +Cc: cygwin

--- Jay Krell <jay.krell@cornell.edu> wrote:

> [... Is this undefined?]
> class X
> {
> public:
>     X* F(int i) { printf("%d", i); return this;}
> };
> 
> int i = 0;
> X x, *px = &x;
> px->F(i++)->F(i++)->F(i++);
> 
> is the expected output 012 or is it undefined?

Undefined.  The C++ Standard requires a sequence point before the
function is called but not before its argument are evaluated.  And
the "->" operators don't impose an evaluation order on their operands
either.

This has some interesting consequences.  Consider:

   cout << 'a' << flush;

The obvious implementation would be to make "flush" an object whose
constructor flushes the stream (although you'd have to pass the stream
as an argument then).

But that won't work because there's nothing to stop the implementation
from constructing "flush" before calling either operator<<.

So the iostream package uses a different solution.  It makes "flush" a
function pointer.  By itself, "flush" does nothing.  But an overloaded
operator<< accepts "flush" as an argument and *it* flushes the stream.

All this is necessary because the order of evaluation of operands above
is unspecified.  (Except that all operands will be evaluated before the
function is called.)  All that's really guaranteed is that the
operator<< calls will be evaluated left-to-right.

> [...] 
> [intro.execution]1.8.17 "..There is also a sequence point after the
> copying
> of a returned value and before the execution of any expressions
> outside the
> function". I don't know if that "copying of a returned value" applies
> to
> pointers and references, and I find "expressions outside the
> function"
> unclear.
> 
> Ordinarily, the sides of a -> I don't believe have a defined order of
> evaluation:

True.

> [...] 

> 
> "sequence point" is not in the index..

It is in my copy.  Maybe you're looking at a draft?  "point" is a
subtopic under "sequence."

=====
-- 
Opinions expressed above are not necessarily my employer's.
James M. Stern
ITG Inc.  Culver City, CA (213) 270-7955

__________________________________________________
Do You Yahoo!?
Talk to your friends online with Yahoo! Messenger.
http://im.yahoo.com

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-13  2:07 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-13  2:07 UTC (permalink / raw)
  To: Bernard Dautrevaux; +Cc: swe sd, cygwin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 7781 bytes --]

Bernard, we are in agreement though your facts are more complete as to
exactly where the sequence points are. My wording was perhaps confusing.

>> I do not yet know if this code is undefined, but certainly
>> the outcome of
>> code like
>> i = i++;
>> i = ++i;
>> i = i--;
>> i = --i;
>> printf("%d%d", i, ++i);
>> printf("%d%d", --i, ++i);
>> etc.
>>
>> is.
>NO it isn't!... In "printf("%d%d", i, ++i);" and "printf("%d%d", --i,
++i);"
>you do NOT know in which order the parameters of printf are evaluated; note
>that this order can be, and often is, different between both calls to
>printf.

I was saying that it is undefined, not that it is defined..

 - Jay

-----Original Message-----
From: Bernard Dautrevaux <Dautrevaux@microprocess.com>
To: 'Jay Krell' <jay.krell@cornell.edu>; swe sd <ccwork@hotmail.com>
Cc: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
Date: Monday, March 13, 2000 1:54 AM
Subject: RE: problem in C++ pointer


>> -----Original Message-----
>> From: Jay Krell [ mailto:jay.krell@cornell.edu ]
>> Sent: Sunday, March 12, 2000 9:09 AM
>> To: swe sd
>> Cc: cygwin@sourceware.cygnus.com
>> Subject: Re: problem in C++ pointer
>>
>>
>> The behavior at a different time and place of code with
>> undefined behavior
>> is not entirely relevant. Different processors, different
>> command lines,
>> different optimizations (possibly processor specific),
>> different versions,
>> can lead to different definitions of undefined behavior.
>> Still, sometimes
>> undefined behavior is predictable.
>>
>> I do not yet know if this code is undefined, but certainly
>> the outcome of
>> code like
>> i = i++;
>> i = ++i;
>> i = i--;
>> i = --i;
>> printf("%d%d", i, ++i);
>> printf("%d%d", --i, ++i);
>> etc.
>>
>> is.
>
>NO it isn't!... In "printf("%d%d", i, ++i);" and "printf("%d%d", --i,
++i);"
>you do NOT know in which order the parameters of printf are evaluated; note
>that this order can be, and often is, different between both calls to
>printf.
>
>Thus if i == 5, "printf("%d%d", i, ++i);" can display either "56" or "66",
>then i == 6, then "printf("%d%d", --i, ++i);" can display either "56" or
>"76" and then i is still 6.
>
>Note that this is the same case if you wite "j = (--i)*(++i);"; you have no
>clear Idea of what you'll get :-)...
>
>In C and C++ there is only FOUR points where sequencing of operations is
>guaranteed (and only as far as the final result is concerned, not memory
>accesses in some cases):
>1)  Between instructions (that is at each occurence of a semicolon or
>closing brace)
>2)  Between the evaluation of the left-hand-side (lvalue) of an "=", "." or
>"->" operator and the actual access to the refered-to lvalue (assignement
to
>it, or access to a member of, including call of a member function)
>3)  Between the evaluation of all the parameters of a function and its
call,
>and between the actual use of the returned value (store or use in an
>expression) and any other code (that mean that calling the function and
>using the result is implicitely atomic)
>4)  At short-circuit operators (|| and &&) where the left expression is
>evaluated before the  right one.
>5)  At each comma operator; be be VERY careful: the comma operator is NOT
>the same as the comma used to separate arguments of a function call. The
>comma operator is separating two expresseions that are evaluated in order
>(first the left one, then the right one), then the comma operator DISCARDS
>the result of the left expression and yields the value of the right one.
>
>Apart form these cases (and for the sub-expressions of a short-circuit or
>comma operator) the order of evaluation of the components of an expression
>is NOT defined and may change due to very obscure reasons known only by the
>compiler (as the number of registers needed to evaluate an expression or
>store its result, or the need to keep some intermediate non-changing value
>for further use in a subsequent instruction).
>
>> If it isn't clear if code falls into this pattern, that's probably
>> enough reason to not write code like it. But even so, if it
>> is defined, it
>> is a bug if Gcc doesn't consistently give it the standard definition.
>
>The code pattern above IS undefined, thus can give you ANY result, even the
>right one :-)
>
>>
>> Here's a good imho boiled down example:
>> class X
>> {
>> public:
>>     X* F(int i) { printf("%d", i); return this;}
>> };
>>
>> int i = 0;
>> X x, *px = &x;
>> px->F(i++)->F(i++)->F(i++);
>>
>> is the expected output 012 or is it undefined?
>
>This is undefined;
>
>> Could it reasonably be 000, if none of the storages occur
>> till after all
>> parameters are evaluated but before any functoins are called?
>
>It could NOT be 000, as (form C++ point of view) i++ directly change the
"i"
>variable, be it in memory or elsewhere; so it could be 012, 021, 120, 102,
>210, or 201 but nothing else (I think its enough :-))
>
>>
>> according to the parts of the standard I can find and decipher:
>> [expr] 5.0.2: "..uses of overloaded operators are transformed
>> into function
>> calls as described in 13.5. Overloaded operators obey rules for syntax
>> specifidd in this clause, but the requirements of operand
>> type, lvalue, and
>> evaluation order are replaced by the rules for function call".
>>
>> I couldn't find the evaluation order for function calls except
>>
>> [intro.execution]1.8.17 "..There is also a sequence point
>> after the copying
>> of a returned value and before the execution of any
>> expressions outside the
>> function". I don't know if that "copying of a returned value"
>> applies to
>> pointers and references, and I find "expressions outside the function"
>> unclear.
>
>This is needed in C++ as copying the result may need implicitely calling an
>user defined cast operator or copy constructor and that avoiding incorrect
>evaluation order dependencies could be very difficult.
>
>>
>> Ordinarily, the sides of a -> I don't believe have a defined order of
>> evaluation:
>
>They have one although a quite trivial one: the left side of "->" have to
be
>evaluated BEFORE the call can be placed, but the ARGUMENTS of the call can
>be evaluated BEFORE, AFTER, or INTERMIXED with the evaluation of the left
>part of "->".
>
>>
>> eg:
>> class C
>> {
>> public:
>> int i;
>> C(int i) { this->i = i ; }
>> void F(C* c) { printf("%d%d", this->i, c->i); }
>> };
>>
>> C carray[2] = { C(0), C(1) };
>> C* pc = carray;
>>
>> (pc++)->F(pc++);
>>
>> Is the output defined?
>
>No, the order of the two "pc++" is undefined.
>
>> It could "reasonably" be
>> 01
>> 10
>
>Yes
>
>> 00
>
>I don't think so; this would mean parallelizing the two "p++", thus
breaking
>their implicit character of atomicity.
>
>> ?
>>
>> I'm assuming the order of eval of an unoverloaded -> is the same, if
>> defined, as the order of eval of ".".
>
>Yes.
>
>>
>> "sequence point" is not in the index..
>>
>>  - Jay
>>
>
>Note that all this is quite intricated and was explicitely left undefined
to
>allow the optimizer to do its work. There is only one rule to follow: NEVER
>modify the same variable twice in the same instruction.
>
>If you NEED such a construct, introduce intermediate variables and remove
>the offending order dependency. Note that IIRC gcc with "-Wall" will warn
>you of these incorrect order dependencies (among lots of other dubious
>constructs ;->).
>
>Hope this helps,
>
> Bernard
>
>--------------------------------------------
>Bernard Dautrevaux
>Microprocess Ingéniérie
>97 bis, rue de Colombes
>92400 COURBEVOIE
>FRANCE
>Tel: +33 (0) 1 47 68 80 80
>Fax: +33 (0) 1 47 88 97 85
>e-mail: dautrevaux@microprocess.com
> b.dautrevaux@usa.net
>--------------------------------------------


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: problem in C++ pointer
@ 2000-03-13  1:54 Bernard Dautrevaux
  0 siblings, 0 replies; 12+ messages in thread
From: Bernard Dautrevaux @ 2000-03-13  1:54 UTC (permalink / raw)
  To: 'Jay Krell', swe sd; +Cc: cygwin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 6663 bytes --]

> -----Original Message-----
> From: Jay Krell [ mailto:jay.krell@cornell.edu ]
> Sent: Sunday, March 12, 2000 9:09 AM
> To: swe sd
> Cc: cygwin@sourceware.cygnus.com
> Subject: Re: problem in C++ pointer
> 
> 
> The behavior at a different time and place of code with 
> undefined behavior
> is not entirely relevant. Different processors, different 
> command lines,
> different optimizations (possibly processor specific), 
> different versions,
> can lead to different definitions of undefined behavior. 
> Still, sometimes
> undefined behavior is predictable.
> 
> I do not yet know if this code is undefined, but certainly 
> the outcome of
> code like
> i = i++;
> i = ++i;
> i = i--;
> i = --i;
> printf("%d%d", i, ++i);
> printf("%d%d", --i, ++i);
> etc.
> 
> is. 

NO it isn't!... In "printf("%d%d", i, ++i);" and "printf("%d%d", --i, ++i);"
you do NOT know in which order the parameters of printf are evaluated; note
that this order can be, and often is, different between both calls to
printf. 

Thus if i == 5, "printf("%d%d", i, ++i);" can display either "56" or "66",
then i == 6, then "printf("%d%d", --i, ++i);" can display either "56" or
"76" and then i is still 6. 

Note that this is the same case if you wite "j = (--i)*(++i);"; you have no
clear Idea of what you'll get :-)...

In C and C++ there is only FOUR points where sequencing of operations is
guaranteed (and only as far as the final result is concerned, not memory
accesses in some cases):
1)  Between instructions (that is at each occurence of a semicolon or
closing brace)
2)  Between the evaluation of the left-hand-side (lvalue) of an "=", "." or
"->" operator and the actual access to the refered-to lvalue (assignement to
it, or access to a member of, including call of a member function)
3)  Between the evaluation of all the parameters of a function and its call,
and between the actual use of the returned value (store or use in an
expression) and any other code (that mean that calling the function and
using the result is implicitely atomic)
4)  At short-circuit operators (|| and &&) where the left expression is
evaluated before the  right one.
5)  At each comma operator; be be VERY careful: the comma operator is NOT
the same as the comma used to separate arguments of a function call. The
comma operator is separating two expresseions that are evaluated in order
(first the left one, then the right one), then the comma operator DISCARDS
the result of the left expression and yields the value of the right one.

Apart form these cases (and for the sub-expressions of a short-circuit or
comma operator) the order of evaluation of the components of an expression
is NOT defined and may change due to very obscure reasons known only by the
compiler (as the number of registers needed to evaluate an expression or
store its result, or the need to keep some intermediate non-changing value
for further use in a subsequent instruction).

> If it isn't clear if code falls into this pattern, that's probably
> enough reason to not write code like it. But even so, if it 
> is defined, it
> is a bug if Gcc doesn't consistently give it the standard definition.

The code pattern above IS undefined, thus can give you ANY result, even the
right one :-)

> 
> Here's a good imho boiled down example:
> class X
> {
> public:
>     X* F(int i) { printf("%d", i); return this;}
> };
> 
> int i = 0;
> X x, *px = &x;
> px->F(i++)->F(i++)->F(i++);
> 
> is the expected output 012 or is it undefined?

This is undefined; 

> Could it reasonably be 000, if none of the storages occur 
> till after all
> parameters are evaluated but before any functoins are called?

It could NOT be 000, as (form C++ point of view) i++ directly change the "i"
variable, be it in memory or elsewhere; so it could be 012, 021, 120, 102,
210, or 201 but nothing else (I think its enough :-))

> 
> according to the parts of the standard I can find and decipher:
> [expr] 5.0.2: "..uses of overloaded operators are transformed 
> into function
> calls as described in 13.5. Overloaded operators obey rules for syntax
> specifidd in this clause, but the requirements of operand 
> type, lvalue, and
> evaluation order are replaced by the rules for function call".
> 
> I couldn't find the evaluation order for function calls except
> 
> [intro.execution]1.8.17 "..There is also a sequence point 
> after the copying
> of a returned value and before the execution of any 
> expressions outside the
> function". I don't know if that "copying of a returned value" 
> applies to
> pointers and references, and I find "expressions outside the function"
> unclear.

This is needed in C++ as copying the result may need implicitely calling an
user defined cast operator or copy constructor and that avoiding incorrect
evaluation order dependencies could be very difficult.

> 
> Ordinarily, the sides of a -> I don't believe have a defined order of
> evaluation:

They have one although a quite trivial one: the left side of "->" have to be
evaluated BEFORE the call can be placed, but the ARGUMENTS of the call can
be evaluated BEFORE, AFTER, or INTERMIXED with the evaluation of the left
part of "->". 

> 
> eg:
> class C
> {
> public:
> int i;
> C(int i) { this->i = i ; }
> void F(C* c) { printf("%d%d", this->i, c->i); }
> };
> 
> C carray[2] = { C(0), C(1) };
> C* pc = carray;
> 
> (pc++)->F(pc++);
> 
> Is the output defined?

No, the order of the two "pc++" is undefined.

> It could "reasonably" be
> 01
> 10

Yes

> 00

I don't think so; this would mean parallelizing the two "p++", thus breaking
their implicit character of atomicity.
 
> ?
> 
> I'm assuming the order of eval of an unoverloaded -> is the same, if
> defined, as the order of eval of ".".

Yes.

> 
> "sequence point" is not in the index..
> 
>  - Jay
> 

Note that all this is quite intricated and was explicitely left undefined to
allow the optimizer to do its work. There is only one rule to follow: NEVER
modify the same variable twice in the same instruction.

If you NEED such a construct, introduce intermediate variables and remove
the offending order dependency. Note that IIRC gcc with "-Wall" will warn
you of these incorrect order dependencies (among lots of other dubious
constructs ;->).

Hope this helps,

		Bernard

--------------------------------------------
Bernard Dautrevaux
Microprocess Ingéniérie
97 bis, rue de Colombes
92400 COURBEVOIE
FRANCE
Tel:	+33 (0) 1 47 68 80 80
Fax:	+33 (0) 1 47 88 97 85
e-mail:	dautrevaux@microprocess.com
		b.dautrevaux@usa.net
-------------------------------------------- 

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-12 19:51 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-12 19:51 UTC (permalink / raw)
  To: swe sd; +Cc: cygwin

>I just wonder what is the different between the original code
>(using a single "cout", see test.cc attached) and new code
>(use another cout to print ++X[0], above).

The difference is that there is definitely a "sequence point" at every
semicolon. The effects of code to the left of a semicolon are guaranteed to
be visible before the effects of code to the right of the same semicolon.

int i, j, k;
    F(j = i++, k = i++);
is undefined, the parameters can be evaluated in any order even sort of
simultaneously, whereas
    j = i++;
    k = i++;
    F(j, k);
and
    k = i++;
    j = i++;
    F(j, k);

are defined. The first line must be completely executed before the second
line.

>    Actually, I tried the original program many time on my PC
>running Cygnus. To remove external factor, I close all other
>program after a re-boot.

I got the same behavior as you, with 2.95.2 to as well. I tried reading the
assembly (gcc -s x.cpp, then look at the file x.s) but it didn't include
commented out C++ source so was too hard to follow.

 - Jay

-----Original Message-----
From: swe sd <ccwork@hotmail.com>
To: jay.krell@cornell.edu <jay.krell@cornell.edu>
Cc: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
Date: Sunday, March 12, 2000 7:52 AM
Subject: Re: problem in C++ pointer


>  First of all, thanks for you kindy answer ...
>  I have the last question. I rewrite the program as follow:
>     line 1:  #include <iostream>
>     line 2:  void main()
>     line 3:  { const int size=10;
>     line 4:    int A[size];
>     line 5:    int *X=NULL, i;
>     line 6:    for (i=0;i<size;i++) A[i]=i;
>     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
>     line 8:    X=A;
>     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>     line 10:       <<*X<<endl
>     line 11:       <<*X+5<<endl
>     line 12:       <<*X<<" "<<A[0]<<endl
>     line 13:       <<5+X[0]<<endl
>     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl;
>     line 15:   cout<<++X[0]<<endl;    //the change here
>     line 16: }
>    and executing it gives output:
>           $./a.out
>           0 0x259fd7c 0x259fd7c
>           0 0x259fd7c 0x259fd7c
>           0
>           5
>           0 0
>           5
>           X[0]=0
>           1
>    Obviously, it gives the correct answer (line 7 = line 9). I
>just wonder what is the different between the original code (using
>a single "cout", see test.cc attached) and new code (use another
>cout to print ++X[0], above).
>    Actually, I tried the original program many time on my PC
>running Cygnus. To remove external factor, I close all other
>program after a re-boot. But the result is still wrong (see last e-mail).
>    Then, to test my program is correct or not, I tried it on a
>UNIX SVR with gcc compiler. Then the program works properly.
>    So, I just conclude there is some wrong with the cygwin, or
>not as good as gcc. Thanks.
>______________________________________________________
>Get Your Private, Free Email at http://www.hotmail.com
>


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-12  7:52 swe sd
  0 siblings, 0 replies; 12+ messages in thread
From: swe sd @ 2000-03-12  7:52 UTC (permalink / raw)
  To: jay.krell; +Cc: cygwin

[-- Attachment #1: Type: text/plain, Size: 1673 bytes --]

  First of all, thanks for you kindy answer ...
  I have the last question. I rewrite the program as follow:
     line 1:  #include <iostream>
     line 2:  void main()
     line 3:  { const int size=10;
     line 4:    int A[size];
     line 5:    int *X=NULL, i;
     line 6:    for (i=0;i<size;i++) A[i]=i;
     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
     line 8:    X=A;
     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
     line 10:       <<*X<<endl
     line 11:       <<*X+5<<endl
     line 12:       <<*X<<" "<<A[0]<<endl
     line 13:       <<5+X[0]<<endl
     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl;
     line 15:   cout<<++X[0]<<endl;    //the change here
     line 16: }
    and executing it gives output:
           $./a.out
           0 0x259fd7c 0x259fd7c
           0 0x259fd7c 0x259fd7c
           0
           5
           0 0
           5
           X[0]=0
           1
    Obviously, it gives the correct answer (line 7 = line 9). I
just wonder what is the different between the original code (using
a single "cout", see test.cc attached) and new code (use another
cout to print ++X[0], above).
    Actually, I tried the original program many time on my PC
running Cygnus. To remove external factor, I close all other
program after a re-boot. But the result is still wrong (see last e-mail).
    Then, to test my program is correct or not, I tried it on a
UNIX SVR with gcc compiler. Then the program works properly.
    So, I just conclude there is some wrong with the cygwin, or
not as good as gcc. Thanks.
______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com

[-- Attachment #2: test.cc --]
[-- Type: text/x-c, Size: 406 bytes --]

#include <stdio.h>
#include <iostream.h>

void main()
{ const int size=10;
  int A[size];
  int *X=NULL, i;
  
  for (i=0;i<size;i++) A[i]=i;
  cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
  X=A;
  cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
      <<*X<<endl
      <<*X+5<<endl
      <<*X<<" "<<A[0]<<endl
      <<5+X[0]<<endl
      <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
      <<++X[0]<<endl;
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-12  0:06 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-12  0:06 UTC (permalink / raw)
  To: swe sd; +Cc: cygwin

The behavior at a different time and place of code with undefined behavior
is not entirely relevant. Different processors, different command lines,
different optimizations (possibly processor specific), different versions,
can lead to different definitions of undefined behavior. Still, sometimes
undefined behavior is predictable.

I do not yet know if this code is undefined, but certainly the outcome of
code like
i = i++;
i = ++i;
i = i--;
i = --i;
printf("%d%d", i, ++i);
printf("%d%d", --i, ++i);
etc.

is. If it isn't clear if code falls into this pattern, that's probably
enough reason to not write code like it. But even so, if it is defined, it
is a bug if Gcc doesn't consistently give it the standard definition.

Here's a good imho boiled down example:
class X
{
public:
    X* F(int i) { printf("%d", i); return this;}
};

int i = 0;
X x, *px = &x;
px->F(i++)->F(i++)->F(i++);

is the expected output 012 or is it undefined?
Could it reasonably be 000, if none of the storages occur till after all
parameters are evaluated but before any functoins are called?

according to the parts of the standard I can find and decipher:
[expr] 5.0.2: "..uses of overloaded operators are transformed into function
calls as described in 13.5. Overloaded operators obey rules for syntax
specifidd in this clause, but the requirements of operand type, lvalue, and
evaluation order are replaced by the rules for function call".

I couldn't find the evaluation order for function calls except

[intro.execution]1.8.17 "..There is also a sequence point after the copying
of a returned value and before the execution of any expressions outside the
function". I don't know if that "copying of a returned value" applies to
pointers and references, and I find "expressions outside the function"
unclear.

Ordinarily, the sides of a -> I don't believe have a defined order of
evaluation:

eg:
class C
{
public:
int i;
C(int i) { this->i = i ; }
void F(C* c) { printf("%d%d", this->i, c->i); }
};

C carray[2] = { C(0), C(1) };
C* pc = carray;

(pc++)->F(pc++);

Is the output defined?
It could "reasonably" be
01
10
00
?

I'm assuming the order of eval of an unoverloaded -> is the same, if
defined, as the order of eval of ".".

"sequence point" is not in the index..

 - Jay

-----Original Message-----
From: swe sd <ccwork@hotmail.com>
To: jay.krell@cornell.edu <jay.krell@cornell.edu>
Cc: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
Date: Saturday, March 11, 2000 9:20 PM
Subject: Re: problem in C++ pointer


>  I do not agree. I execute the same program on a UNIX station with gcc
>compiler and it works fine ... ie the output of line 7 is
>same as the output of line 9.
>
>>From: "Jay Krell" <jay.krell@cornell.edu>
>>To: "swe sd" <ccwork@hotmail.com>, <cygwin@sourceware.cygnus.com>
>>Subject: Re: problem in C++ pointer
>>Date: Sat, 11 Mar 2000 16:31:28 -0800
>>
>>Your code might be triggering undefined behavior in C++, because of the
>>++X[0] in the same statement where you otherwise read X[0]. Definitely
>>something like
>>printf("%d%d", X[0], ++X[0]);
>>is undefined but I've read something along the lines that when the
>>operator's are actually overloaded, function calls, that the order of
>>evaluation becomes defined..
>>
>> >     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>> >     line 10:       <<*X<<endl
>> >     line 11:       <<*X+5<<endl
>> >     line 12:       <<*X<<" "<<A[0]<<endl
>> >     line 13:       <<5+X[0]<<endl
>> >     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>> >     line 15:       <<++X[0]<<endl
>>
>>something like, skipping endl.
>>cout.<<(A[0]).<<(" ").<<(&A).<<(" ").<<(&A[0]).<<(*X).<<(*X+5).<<(*X).<<("
>>").<<A[0].<<(5+X[0]).<<(( X[0]==0 ? "X[0]=0" : "X[0]!=0")).<<(++X[0]);
>>
>>  - Jay
>>
>>-----Original Message-----
>>From: swe sd <ccwork@hotmail.com>
>>To: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
>>Date: Saturday, March 11, 2000 9:31 AM
>>Subject: B20: problem in C++ pointer
>>
>>
>> >   I compiled the following program (attachment test.cc):
>> >     line 1:  #include <iostream>
>> >     line 2:  void main()
>> >     line 3:  { const int size=10;
>> >     line 4:    int A[size];
>> >     line 5:    int *X=NULL, i;
>> >     line 6:    for (i=0;i<size;i++) A[i]=i;
>> >     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
>> >     line 8:    X=A;
>> >     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>> >     line 10:       <<*X<<endl
>> >     line 11:       <<*X+5<<endl
>> >     line 12:       <<*X<<" "<<A[0]<<endl
>> >     line 13:       <<5+X[0]<<endl
>> >     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>> >     line 15:       <<++X[0]<<endl
>> >     line 16: }
>> >    and executing it gives output:
>> >           $./a.out
>> >           0 0x259fd7c 0x259fd7c
>> >           1 0x259fd7c 0x259fd7c
>> >           1
>> >           6
>> >           1 1
>> >           6
>> >           X[0]!=0
>> >           1
>> >    Obviously, the output of line 9 is different from line 7 which >
>> >should be the same indeed. Is there anything wrong ? Thanks.
>
>______________________________________________________
>Get Your Private, Free Email at http://www.hotmail.com
>


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-11 21:20 swe sd
  0 siblings, 0 replies; 12+ messages in thread
From: swe sd @ 2000-03-11 21:20 UTC (permalink / raw)
  To: jay.krell; +Cc: cygwin

  I do not agree. I execute the same program on a UNIX station with gcc 
compiler and it works fine ... ie the output of line 7 is
same as the output of line 9.

>From: "Jay Krell" <jay.krell@cornell.edu>
>To: "swe sd" <ccwork@hotmail.com>, <cygwin@sourceware.cygnus.com>
>Subject: Re: problem in C++ pointer
>Date: Sat, 11 Mar 2000 16:31:28 -0800
>
>Your code might be triggering undefined behavior in C++, because of the
>++X[0] in the same statement where you otherwise read X[0]. Definitely
>something like
>printf("%d%d", X[0], ++X[0]);
>is undefined but I've read something along the lines that when the
>operator's are actually overloaded, function calls, that the order of
>evaluation becomes defined..
>
> >     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
> >     line 10:       <<*X<<endl
> >     line 11:       <<*X+5<<endl
> >     line 12:       <<*X<<" "<<A[0]<<endl
> >     line 13:       <<5+X[0]<<endl
> >     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
> >     line 15:       <<++X[0]<<endl
>
>something like, skipping endl.
>cout.<<(A[0]).<<(" ").<<(&A).<<(" ").<<(&A[0]).<<(*X).<<(*X+5).<<(*X).<<("
>").<<A[0].<<(5+X[0]).<<(( X[0]==0 ? "X[0]=0" : "X[0]!=0")).<<(++X[0]);
>
>  - Jay
>
>-----Original Message-----
>From: swe sd <ccwork@hotmail.com>
>To: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
>Date: Saturday, March 11, 2000 9:31 AM
>Subject: B20: problem in C++ pointer
>
>
> >   I compiled the following program (attachment test.cc):
> >     line 1:  #include <iostream>
> >     line 2:  void main()
> >     line 3:  { const int size=10;
> >     line 4:    int A[size];
> >     line 5:    int *X=NULL, i;
> >     line 6:    for (i=0;i<size;i++) A[i]=i;
> >     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
> >     line 8:    X=A;
> >     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
> >     line 10:       <<*X<<endl
> >     line 11:       <<*X+5<<endl
> >     line 12:       <<*X<<" "<<A[0]<<endl
> >     line 13:       <<5+X[0]<<endl
> >     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
> >     line 15:       <<++X[0]<<endl
> >     line 16: }
> >    and executing it gives output:
> >           $./a.out
> >           0 0x259fd7c 0x259fd7c
> >           1 0x259fd7c 0x259fd7c
> >           1
> >           6
> >           1 1
> >           6
> >           X[0]!=0
> >           1
> >    Obviously, the output of line 9 is different from line 7 which > 
> >should be the same indeed. Is there anything wrong ? Thanks.

______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-11 16:33 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-11 16:33 UTC (permalink / raw)
  To: swe sd, cygwin

Darn, sent that before finishing..
>something like, skipping endl.
>cout.<<(A[0]).<<(" ").<<(&A).<<(" ").<<(&A[0]).<<(*X).<<(*X+5).<<(*X).<<("
>").<<A[0].<<(5+X[0]).<<(( X[0]==0 ? "X[0]=0" : "X[0]!=0")).<<(++X[0]);

something like, skipping endl.
cout
 .print(A[0])
 .print(" ")
 .print(&A)
 .print(" ")
 .print(&A[0])
 .print(*X)
 .print(*X+5)
 .print(*X)
 .print(" ")
 .printA[0]
 .print(5+X[0])
 .print(( X[0]==0 ? "X[0]=0" : "X[0]!=0"))
 .print(++X[0]);

whether or not the left of the dots is supposed to be evaluated before the
right and the parameters to "print", I'm not sure. See "sequence point" in
the standard..

 - Jay

-----Original Message-----
From: Jay Krell <jay.krell@cornell.edu>
To: swe sd <ccwork@hotmail.com>; cygwin@sourceware.cygnus.com
<cygwin@sourceware.cygnus.com>
Date: Saturday, March 11, 2000 4:31 PM
Subject: Re: problem in C++ pointer


>Your code might be triggering undefined behavior in C++, because of the
>++X[0] in the same statement where you otherwise read X[0]. Definitely
>something like
>printf("%d%d", X[0], ++X[0]);
>is undefined but I've read something along the lines that when the
>operators are actually overloaded, function calls, that the order of
>evaluation becomes defined..
>
>>     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>>     line 10:       <<*X<<endl
>>     line 11:       <<*X+5<<endl
>>     line 12:       <<*X<<" "<<A[0]<<endl
>>     line 13:       <<5+X[0]<<endl
>>     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>>     line 15:       <<++X[0]<<endl
>
>something like, skipping endl.
>cout.<<(A[0]).<<(" ").<<(&A).<<(" ").<<(&A[0]).<<(*X).<<(*X+5).<<(*X).<<("
>").<<A[0].<<(5+X[0]).<<(( X[0]==0 ? "X[0]=0" : "X[0]!=0")).<<(++X[0]);
>
> - Jay
>
>-----Original Message-----
>From: swe sd <ccwork@hotmail.com>
>To: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
>Date: Saturday, March 11, 2000 9:31 AM
>Subject: B20: problem in C++ pointer
>
>
>>   I compiled the following program (attachment test.cc):
>>     line 1:  #include <iostream>
>>     line 2:  void main()
>>     line 3:  { const int size=10;
>>     line 4:    int A[size];
>>     line 5:    int *X=NULL, i;
>>     line 6:    for (i=0;i<size;i++) A[i]=i;
>>     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
>>     line 8:    X=A;
>>     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>>     line 10:       <<*X<<endl
>>     line 11:       <<*X+5<<endl
>>     line 12:       <<*X<<" "<<A[0]<<endl
>>     line 13:       <<5+X[0]<<endl
>>     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>>     line 15:       <<++X[0]<<endl
>>     line 16: }
>>    and executing it gives output:
>>           $./a.out
>>           0 0x259fd7c 0x259fd7c
>>           1 0x259fd7c 0x259fd7c
>>           1
>>           6
>>           1 1
>>           6
>>           X[0]!=0
>>           1
>>    Obviously, the output of line 9 is different from line 7 which should
>be
>>the same indeed. Is there anything wrong ? Thanks.
>>
>>______________________________________________________
>>Get Your Private, Free Email at http://www.hotmail.com
>>
>


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: problem in C++ pointer
@ 2000-03-11 16:29 Jay Krell
  0 siblings, 0 replies; 12+ messages in thread
From: Jay Krell @ 2000-03-11 16:29 UTC (permalink / raw)
  To: swe sd, cygwin

Your code might be triggering undefined behavior in C++, because of the
++X[0] in the same statement where you otherwise read X[0]. Definitely
something like
printf("%d%d", X[0], ++X[0]);
is undefined but I've read something along the lines that when the
operator's are actually overloaded, function calls, that the order of
evaluation becomes defined..

>     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>     line 10:       <<*X<<endl
>     line 11:       <<*X+5<<endl
>     line 12:       <<*X<<" "<<A[0]<<endl
>     line 13:       <<5+X[0]<<endl
>     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>     line 15:       <<++X[0]<<endl

something like, skipping endl.
cout.<<(A[0]).<<(" ").<<(&A).<<(" ").<<(&A[0]).<<(*X).<<(*X+5).<<(*X).<<("
").<<A[0].<<(5+X[0]).<<(( X[0]==0 ? "X[0]=0" : "X[0]!=0")).<<(++X[0]);

 - Jay

-----Original Message-----
From: swe sd <ccwork@hotmail.com>
To: cygwin@sourceware.cygnus.com <cygwin@sourceware.cygnus.com>
Date: Saturday, March 11, 2000 9:31 AM
Subject: B20: problem in C++ pointer


>   I compiled the following program (attachment test.cc):
>     line 1:  #include <iostream>
>     line 2:  void main()
>     line 3:  { const int size=10;
>     line 4:    int A[size];
>     line 5:    int *X=NULL, i;
>     line 6:    for (i=0;i<size;i++) A[i]=i;
>     line 7:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl;
>     line 8:    X=A;
>     line 9:    cout<<A[0]<<" "<<&A<<" "<<&A[0]<<endl
>     line 10:       <<*X<<endl
>     line 11:       <<*X+5<<endl
>     line 12:       <<*X<<" "<<A[0]<<endl
>     line 13:       <<5+X[0]<<endl
>     line 14:       <<( X[0]==0 ? "X[0]=0" : "X[0]!=0")<<endl
>     line 15:       <<++X[0]<<endl
>     line 16: }
>    and executing it gives output:
>           $./a.out
>           0 0x259fd7c 0x259fd7c
>           1 0x259fd7c 0x259fd7c
>           1
>           6
>           1 1
>           6
>           X[0]!=0
>           1
>    Obviously, the output of line 9 is different from line 7 which should
be
>the same indeed. Is there anything wrong ? Thanks.
>
>______________________________________________________
>Get Your Private, Free Email at http://www.hotmail.com
>


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2000-03-17 13:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-17  9:48 problem in C++ pointer Jay Krell
  -- strict thread matches above, loose matches on Subject: below --
2000-03-17 13:26 Heribert Dahms
2000-03-17 13:15 Jay Krell
2000-03-16  8:39 James Stern
2000-03-13  2:07 Jay Krell
2000-03-13  1:54 Bernard Dautrevaux
2000-03-12 19:51 Jay Krell
2000-03-12  7:52 swe sd
2000-03-12  0:06 Jay Krell
2000-03-11 21:20 swe sd
2000-03-11 16:33 Jay Krell
2000-03-11 16:29 Jay Krell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).