473,402 Members | 2,046 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

About comma expression.

I used comma expression in two different ways in the following code.
This code is reduced from some more complex code. I don't have the
ability to write in the 2nd way for the complex code.

I want the output of the 2nd is wanted. Do you have any idea how to
modify the 1st way such that it gives the same output as the 2nd one?

Thanks,
Peng

#include <iostream>

class plot {
public:
plot &doit(int &i){
std::cout << i << std::endl;
return *this;
}
};

int main ()
{
plot p;
int i = 10;
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted
std::cout << std::endl;
i = 10;
p.doit((++i,i));
p.doit((++i,i)); // output 11 12; 2nd way different from above
}

Dec 1 '05 #1
7 1236
Pe*******@gmail.com wrote:
I used comma expression in two different ways in the following code.
This code is reduced from some more complex code. I don't have the
ability to write in the 2nd way for the complex code.

I want the output of the 2nd is wanted. Do you have any idea how to
modify the 1st way such that it gives the same output as the 2nd one?

Thanks,
Peng

#include <iostream>

class plot {
public:
plot &doit(int &i){
std::cout << i << std::endl;
return *this;
} plot &incdoit(int &i)
{
++i;
doit(i);
} };

int main ()
{
plot p;
int i = 10;
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted
std::cout << std::endl;
i = 10;
p.doit((++i,i));
p.doit((++i,i)); // output 11 12; 2nd way different from above std::cout << std::endl;
i = 10;
p.incdoit(i).incdoit(i); // output 11,12 }

Using preincrement of a variable more than once in an expression results
in unpredictable behaviour, because it is compiler dependent.
To get round this without changing plot::doit() I suggest the changes
shown.

JB
Dec 1 '05 #2

Pe*******@gmail.com wrote:
I used comma expression in two different ways in the following code.
This code is reduced from some more complex code. I don't have the
ability to write in the 2nd way for the complex code.

I want the output of the 2nd is wanted. Do you have any idea how to
modify the 1st way such that it gives the same output as the 2nd one?

Thanks,
Peng

#include <iostream>

class plot {
public:
plot &doit(int &i){
std::cout << i << std::endl;
return *this;
}
};

int main ()
{
plot p;
int i = 10;
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted
std::cout << std::endl;
i = 10;
p.doit((++i,i));
p.doit((++i,i)); // output 11 12; 2nd way different from above
}


Have a look at this

http://www.gotw.ca/gotw/056.htm

If you imagine

p.doit((++i,i)).doit((++i,i));

as the compiler sees it (like a normal function, with the object's this
pointer passed as an extra parameter) you get

doit( &(doit(&p, (++i, i))), (++i, i) );

I think that, despite your use of the comma operator to introduce a
sequence point between ++i and i each time, the fact that the
evaluation of function arguments can happen in any order and can be
interleaved means that you still have undefined behaviour. The second
++i can start before the first one has finished.

http://www.parashift.com/c++-faq-lit...html#faq-39.15

I have stared at your code for quite a while and I'm not 100% sure of
my answer. If I'm wrong, hopefully someone will correct me.

Gavin Deane

Dec 1 '05 #3
n2xssvv g02gfr12930 wrote:
p.doit((++i,i));
p.doit((++i,i)); // output 11 12; 2nd way different from above

Using preincrement of a variable more than once in an expression results
in unpredictable behaviour, because it is compiler dependent.


Not in this case. Comma operator enforces both an ordering and a
sequence point. The left side is FULLY evaluated, and a sequence
point occurs before the right side is evaluated.
Dec 1 '05 #4
Pe*******@gmail.com wrote:
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted

In this case the compiler is allowed to do both the left sides of
the comma operators before doing the sequence point and the right
side. This is undefined behavior.
Dec 1 '05 #5

Ron Natalie wrote:
Pe*******@gmail.com wrote:
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted

In this case the compiler is allowed to do both the left sides of
the comma operators before doing the sequence point and the right
side. This is undefined behavior.


I posted a similar answer, though I wasn't entirely confident I was
right. It's good to see some confirmation. I have another question now.
Can the compiler stop *between* completing the evaluation of ++i and
"doing" the sequence point. I thought would be

start evaluating ++i
finish evaluating ++i // implies sequence point happens

The problem would then arise if we started to evaluate the second ++i
before we had finished evaluating the first one. But then if ++i is a
single machine instruction (which I imagine it would be) then the
compiler couldn't stop part way through evaluating it (this is why I
wasn't 100% sure of my answer to the OP).

You seem to suggest the problem is actually

completely evaluate first ++i
do sequence point for the comma operator

and clearly the nasal demons are summoned if the second ++i is
evaluated between those two steps.

Is my understanding of what you have said correct?

Thanks
Gavin Deane

Dec 1 '05 #6
de*********@hotmail.com wrote:
Ron Natalie wrote:
Pe*******@gmail.com wrote:
p.doit((++i,i)).doit((++i,i));// output 12 12; 1st way; not wanted

In this case the compiler is allowed to do both the left sides of
the comma operators before doing the sequence point and the right
side. This is undefined behavior.


I posted a similar answer, though I wasn't entirely confident I was
right. It's good to see some confirmation. I have another question now.
Can the compiler stop *between* completing the evaluation of ++i and
"doing" the sequence point. I thought would be

start evaluating ++i
finish evaluating ++i // implies sequence point happens

There is no "finish" of a side effect until a sequence point.
If there are two modifications of the same variable happening
for a an allowable ordering before the sequence point, then
you have a problem.

Whether you have interleaved instructions or the subexpressions are
executed in different processors in parallel.
Dec 1 '05 #7
Ron Natalie wrote:
n2xssvv g02gfr12930 wrote:
p.doit((++i,i));
p.doit((++i,i)); // output 11 12; 2nd way different from above

Using preincrement of a variable more than once in an expression
results in unpredictable behaviour, because it is compiler dependent.

Not in this case. Comma operator enforces both an ordering and a
sequence point. The left side is FULLY evaluated, and a sequence
point occurs before the right side is evaluated.

Granted for the comma operators, but these could still be evaluated
before the member function calls, (as actually happened). Personally I
much prefer code that doesn't require such a detailed knowledge of
sequence points, as that is prone to errors both during bug fixing and
development, (this case demonstrates the point). Maybe that's the half
decent engineer in me that prefers to reduce risk created by potential
doubt.

JB
Dec 1 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Derek | last post by:
I came upon the idea of writting a logging class that uses a Python-ish syntax that's easy on the eyes (IMO): int x = 1; double y = 2.5; std::string z = "result"; debug = "Results:", x, y,...
8
by: Bo Sun | last post by:
hi, suppose I have the following expression (all variables are of integer type) result = (first = 2, second = first + 1, third = second + 1); what is the value of result? 1) result is 4....
2
by: benben | last post by:
I am looking for a good example of overloading operator , (operator comma) Any suggestions? Ben
2
by: s.subbarayan | last post by:
Dear all, What does this following piece of code do? #define CONVERT_SELF_PTR(type,in,out) \ (((in) != NULL) ? ((out) = (type *)(in), RETURN_OK) : ERROR_PARAM) especially can someone let...
17
by: kj | last post by:
How can one test if a pointer has been "freed" (i.e. with free())? My naive assumption was that such a pointer would equal NULL, but not so. Thanks, kj -- NOTE: In my address everything...
21
by: siliconwafer | last post by:
Hi, In case of following expression: c = a && --b; if a is 0,b is not evaluated and c directly becomes 0. Does this mean that && operator is given a higher precedence over '--'operator? as...
7
by: JAY | last post by:
There is an example which confuses me, int main() { int a,b,c,d; a=3; b=5; c=a,b; d=(a,b); printf("c=%d",c); printf("d=%d",d);
15
by: Jeroen | last post by:
Hi all, I've got a very specific question about the evaluation order in C++. Assume some kind of custom array class, with an overloaded subscript operator. In the following code: { my_array...
15
by: Lighter | last post by:
In 5.3.3.4 of the standard, the standard provides that "The lvalue-to- rvalue(4.1), array-to-pointer(4.2),and function-to-pointer(4.3) standard conversions are not applied to the operand of...
49
by: Pilcrow | last post by:
In the code below, can someone explain why the asterisks seem to be required on the line labelled 'A' and forbidden on the line labelled 'B'? Thanks in advance for the help....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.