pre, post increment standard behaviour, and friend function declaration

E

eddiew_AUS

while playing around to check <blah> for my personal project, I discovered
an anomaly with my code, compiled using (cringe) visual studio ver 6:


#include<iostream>

using namespace std;

int main( void )
{
int k = 3;
cout << k;
cout << " " << k++ << " " << k << " " << ++k << " ";
cout << k << "\n";
}

produces the expected output of:
3 4 4 4 5

while

#include<iostream>

using namespace std;

int main( void )
{
int k = 3;
cout << k;
cout << " " << k++ << " " << k << " " << ++k << " " << k << "\n";
}

produced the output of
3 4 4 4 3

Q: Is this another example of non-standard microsoft compilers, or a result
of the chained function calls?

And another question:
Q: Is it possible to declare the constructor of class B as a friend function
to class A, and if so what is the syntax?

thanks in advance,
ed.
 
R

Rolf Magnus

eddiew_AUS said:
while playing around to check <blah> for my personal project,

What is said:
I discovered an anomaly with my code, compiled using (cringe) visual
studio ver 6:


#include<iostream>

using namespace std;

int main( void )
{
int k = 3;
cout << k;
cout << " " << k++ << " " << k << " " << ++k << " ";
cout << k << "\n";
}

produces the expected output of:
3 4 4 4 5

I don't see why you would expect that.
while

#include<iostream>

using namespace std;

int main( void )
{
int k = 3;
cout << k;
cout << " " << k++ << " " << k << " " << ++k << " " << k << "\n";
}

produced the output of
3 4 4 4 3

Q: Is this another example of non-standard microsoft compilers, or a
result of the chained function calls?

It's the result of changing k's value multiple times without a sequence
point in between. The behaviour of that code is undefined.
And another question:
Q: Is it possible to declare the constructor of class B as a friend
function to class A, and if so what is the syntax?

I don't think so. Constructors don't have a name.
 
K

Karl Heinz Buchegger

eddiew_AUS said:
int k = 3;
cout << k;
cout << " " << k++ << " " << k << " " << ++k << " ";
cout << k << "\n";
}

produces the expected output of:
3 4 4 4 5

There is no expected output, since the above has
undefined behaviour
Q: Is this another example of non-standard microsoft compilers, or a result
of the chained function calls?

It is a possible result of undefined behaviour. Please check the
groups archive at google. This topic has been beaten to death.
And another question:
Q: Is it possible to declare the constructor of class B as a friend function
to class A, and if so what is the syntax?

No it is not. Constructors don't have names.
 
E

eddiew_AUS

Karl Heinz Buchegger said:
There is no expected output, since the above has
undefined behaviour


It is a possible result of undefined behaviour. Please check the
groups archive at google. This topic has been beaten to death.


No it is not. Constructors don't have names.

Thanks for the replies. I now understand the reasons behind both answers. :/

cheers, ed.
 
E

eddiew_AUS

Rolf Magnus said:
What is "<blah>"?

<blah> is a simple game with which i am challenging my skills at using and
understanding 3rd party code, increasing my understanding of the C++
language and especially the STL, and helping my good programming practices
(spelt with an s or a c??) with a copy of the C++ FAQs by my keyboard.

the object of <blah> is to negotiate a 3 dimensional tunnel at speed. Tunnel
is created using concepts from random walk functions at run-time, with
randomness apparent in the shape of the wall of the tunnel and the
approximate centre of the tunnel.

Not really that relevant to a technical question, but ask away and i'll be
more than happy to discuss any other part of this project :)

cheers, ed.
 
K

Kevin Goodsell

Rolf said:
It's the result of changing k's value multiple times without a sequence
point in between. The behaviour of that code is undefined.

Not true. There are a number of sequence points (before each function
call and return). It's unspecified behavior due to the order of
evaluation of the function parameters.

-Kevin
 
K

Kevin Goodsell

Karl said:
There is no expected output, since the above has
undefined behaviour

Unspecified, but not undefined. At least according to the discussion of
a nearly identical program a week or two ago. There are sequence points
before each function call and return.

The problem, I think, is that in

a.b(c);

it is not specified whether 'a' or 'c' is evaluated first. But I haven't
located the exact section of the standard that says this.

-Kevin
 
R

Rolf Magnus

Kevin said:
Not true. There are a number of sequence points (before each function
call and return). It's unspecified behavior due to the order of
evaluation of the function parameters.

I never get that right.
 
A

Andrey Tarasevich

Kevin said:
...
The problem, I think, is that in

a.b(c);

it is not specified whether 'a' or 'c' is evaluated first. But I haven't
located the exact section of the standard that says this.
...

5/4

Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions [...] is
unspecified [...]
 
K

Kevin Goodsell

Andrey said:
5/4

Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions [...] is
unspecified [...]

The example in that section has me confused. I'm looking at a draft (Nov
1997), so maybe it's different in the final:

i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented

The two statements that are listed as unspecified I think should be
undefined.

Can anyone tell me if this example has been changed? And isn't it true
that the behavior is undefined, not unspecified?

-Kevin
 
A

Andrey Tarasevich

Kevin said:
5/4

Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions [...] is
unspecified [...]

The example in that section has me confused. I'm looking at a draft (Nov
1997), so maybe it's different in the final:

i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented

The two statements that are listed as unspecified I think should be
undefined.

Can anyone tell me if this example has been changed? And isn't it true
that the behavior is undefined, not unspecified?

Yes, the behavior is undefined. The example in 5/4 is defective, as
reported in

http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/cwg_active.html#351

In the OP's case the behavior is still unspecified for the reasons that
you correctly stated in your previous messages.
 
R

Ron Natalie

The example in that section has me confused. I'm looking at a draft (Nov
1997), so maybe it's different in the final
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented

The two statements that are listed as unspecified I think should be
undefined.

You are correct.
Can anyone tell me if this example has been changed? And isn't it true
that the behavior is undefined, not unspecified?
No it's still wrong, even after TC1. Note that the examples do not have any meaning
for defining the language (non-normative).
 
J

Jack Klein

Not true. There are a number of sequence points (before each function
call and return). It's unspecified behavior due to the order of
evaluation of the function parameters.

May or may not be true. There is absolutely nothing in the standard
that prohibits the evaluation of all four terms involving k before
making any calls to the cout insertion operator. In that case the
behavior is undefined.

So depending on the unspecified order of evaluation of the arguments,
it might be undefined behavior, or merely unspecified behavior.
 
J

Jack Klein

Unspecified, but not undefined. At least according to the discussion of
a nearly identical program a week or two ago. There are sequence points
before each function call and return.

No, honestly, it is unspecified as to whether it is undefined or not.
There is nothing in the standard that prevents an implementation from
evaluating all terms involving "k" before calling any of the operator
functions. If an implementation does so, "k" is modified twice
between sequence points, and its value is also accessed two other
times in a manner not involved with calculating the new value. In
this case, then, the behavior is undefined.

On the other hand, if a compiler evaluates each term involving "k"
just before calling the cout insertion operator function, it has
unspecified behavior.
 
K

Kevin Goodsell

Jack said:
May or may not be true. There is absolutely nothing in the standard
that prohibits the evaluation of all four terms involving k before
making any calls to the cout insertion operator. In that case the
behavior is undefined.

So depending on the unspecified order of evaluation of the arguments,
it might be undefined behavior, or merely unspecified behavior.

Good point. That didn't even occur to me. Thanks for pointing it out.

-Kevin
 
K

Karl Heinz Buchegger

Kevin said:
Karl Heinz Buchegger wrote:

Unspecified, but not undefined.

You are right.
At least according to the discussion of
a nearly identical program a week or two ago. There are sequence points
before each function call and return.

The problem, I think, is that in

a.b(c);

it is not specified whether 'a' or 'c' is evaluated first. But I haven't
located the exact section of the standard that says this.

You are searching for
5.2.2-1
and
5.2.2-8

For a discussion of this, see eg.
http://groups.google.at/groups?q=bu...=UTF-8&[email protected]&rnum=4

This post was written by, aehm, me.
 
R

Ron Natalie

Jack Klein said:
No, honestly, it is unspecified as to whether it is undefined or not.
There is nothing in the standard that prevents an implementation from
evaluating all terms involving "k" before calling any of the operator
functions. If an implementation does so, "k" is modified twice
between sequence points, and its value is also accessed two other
times in a manner not involved with calculating the new value. In
this case, then, the behavior is undefined.

Nope, the behavior is simply undefined. The rules say that if the value is
modified twice between sequence point for ANY ALLOWABLE ORDERING
of operations, then the behavior is undefined.
 
A

Andrey Tarasevich

Andrey said:
...
In the OP's case the behavior is still unspecified for the reasons that
you correctly stated in your previous messages.
...

Actually, Jack Klein is right - its undefined. I've seen the reasoning
he uses in his message many times and even used it myself, but somehow I
managed to forget about it completely... :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top