 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Vladimir Guest
|
Posted: Mon Oct 17, 2005 5:13 pm Post subject: UB and operator++() |
|
|
Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
| Quote: |
MyClass i, j;
//...
j = ++i + ++i;
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Tue Oct 18, 2005 10:34 am Post subject: Re: UB and operator++() |
|
|
"Vladimir" <vkiryazev (AT) yandex (DOT) ru> writes:
| Quote: | Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
|
No. The behavior defined.
The order of the evaluation of the two ++i is unspecified, but that's
not why you asked.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Tue Oct 18, 2005 10:38 am Post subject: Re: UB and operator++() |
|
|
Vladimir wrote:
| Quote: | Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
|
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Tue Oct 18, 2005 9:23 pm Post subject: Re: UB and operator++() |
|
|
Victor Bazarov wrote:
| Quote: | Vladimir wrote:
Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
|
What difference does that make? If there is no operator + for
the result of Myclass::operator++, then the program is ill-formed.
It's never going to be undefined behavior.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Wed Oct 19, 2005 1:56 am Post subject: Re: UB and operator++() |
|
|
In article <1129561831.570153.40480 (AT) g47g2000cwa (DOT) googlegroups.com>,
Vladimir <vkiryazev (AT) yandex (DOT) ru> writes
| Quote: | Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
|
No.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Guest
|
Posted: Wed Oct 19, 2005 1:59 am Post subject: Re: UB and operator++() |
|
|
Victor Bazarov wrote:
| Quote: | MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
|
OK, that is a complete example:
#include <iostream>
class MyClass
{
int i_;
public:
MyClass():i_(0) {}
MyClass(int i):i_(i) {}
MyClass& operator++(){++i_; return *this;}
friend MyClass operator+(MyClass& l, MyClass& r)
{
return l.i_ + r.i_;
}
};
int main ()
{
MyClass i = 1, j;
j = ++i + ++i;
}
I would like to know what's happening there. Thanks in advance.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carlos Moreno Guest
|
Posted: Wed Oct 19, 2005 8:37 am Post subject: Re: UB and operator++() |
|
|
Ron Natalie wrote:
| Quote: | Victor Bazarov wrote:
Vladimir wrote:
Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
What difference does that make?
|
That operator+ could be the one incurring in UB.
I agree that that's kind of going off a tangent with respect
to what the OP wanted to know... But still.
Carlos
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Wed Oct 19, 2005 8:44 am Post subject: Re: UB and operator++() |
|
|
Vladimir wrote:
| Quote: | Victor Bazarov wrote:
MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
OK, that is a complete example:
#include <iostream
class MyClass
{
int i_;
public:
MyClass():i_(0) {}
MyClass(int i):i_(i) {}
MyClass& operator++(){++i_; return *this;}
friend MyClass operator+(MyClass& l, MyClass& r)
{
return l.i_ + r.i_;
}
};
int main ()
{
MyClass i = 1, j;
j = ++i + ++i;
}
I would like to know what's happening there. Thanks in advance.
|
I think it's the same as
cout << ++i << ++i;
The expression in question, rewritten in function terms, is
j.operator=(operator+(i.operator++(), i.operator++()));
Let's call 'operator++' 'inc' and 'operator+' 'plus':
j.operator=(plus(i.inc(), i.inc()))
Both calls to 'i.inc()' are performed in unspecified order but (a) one
definitely returns before the other one is entered and (b) both are done
before 'plus' is entered. So, any side effects take place between all
sequence points and no object changes its value twice between sequence
points. And once 'plus' returns, its value is passed to operator=.
Well, given assumptions about normalcy of operator overloads and that
of return value types of those overloads, one could _assume_ nothing
bad is happening. However, this (although somewhat contrived) is not
impossible to encounter in real life:
class MyClass
{
int i_;
template
class LazyEvaluator {
T& ref1, ref2;
const char* op;
T evaluate();
public:
LazyEvaluator(T &r, char const* op);
LazyEvaluator(T &r1, T &r2, char const* op);
operator T() { evaluate(); }
};
public:
MyClass():i_(0) {}
MyClass(int i):i_(i) {}
LazyEvaluator<MyClass> operator++()
{
return LazyEvaluator<MyClass>(*this, "++");
}
friend MyClass operator+(LazyEvaluator<MyClass>& l,
LazyEvaluator<MyClass>& r)
{
return LazyEvaluator<LazyEvaluator(l, r, "+");
}
};
And now imagine that somewhere deep inside 'LazyEvaluator' actually
extracts references to int and performs ++ + ++ in the same expression
(by virtue of some template expression evaluation implementation). That
would suddently have UB, I think.
Of course, I just typed this in, and it's not working code, but just
an example for illustration purposes only.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Thu Oct 20, 2005 2:42 am Post subject: Re: UB and operator++() |
|
|
In article <21S4f.42107$Tf5.12729 (AT) newsread1 (DOT) mlpsca01.us.to.verio.net>,
Victor Bazarov <v.Abazarov (AT) comAcast (DOT) net> writes
| Quote: | Vladimir wrote:
Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
|
It seems unlikely that whether operator+ was overloaded would have any
influence. It might determine whether the code was well formed or not
(i.e. whether it would compile) but I doubt that undefined behaviour
would be an issue.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/
youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maciej Sobczak Guest
|
Posted: Thu Oct 20, 2005 2:46 am Post subject: Re: UB and operator++() |
|
|
Vladimir wrote:
| Quote: | OK, that is a complete example:
#include
class MyClass
{
int i_;
public:
MyClass():i_(0) {}
MyClass(int i):i_(i) {}
MyClass& operator++(){++i_; return *this;}
friend MyClass operator+(MyClass& l, MyClass& r)
{
return l.i_ + r.i_;
}
};
int main ()
{
MyClass i = 1, j;
j = ++i + ++i;
}
I would like to know what's happening there. Thanks in advance.
|
Conceptually, the same as here:
MyClass i = 1, j;
++i; // i.i_ == 2 after this
++i; // i.i_ == 3 after this
j.i_ = i.i_ + i.i_; // j.i_ == 6 after this
The reason is that '+' in your example is an overloaded operator, which
is treated like a regular function in the sense that its parameters have
to be evaluated before this operator is executed. Here, evaluation of
parameters means executing ++i twice, but ++ is another operator, which
(again just like a regular function) is called twice. In this example,
it does not matter what is the order of calling ++ twice (and there is a
sequence point between them), so even if formally this is unspecified,
the result is always well-defined - but it's the math that gives you
this guarantee (for this particular example), not the language.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Guest
|
Posted: Thu Oct 20, 2005 12:52 pm Post subject: Re: UB and operator++() |
|
|
Victor Bazarov wrote:
| Quote: | I think it's the same as
cout << ++i << ++i;
The expression in question, rewritten in function terms, is
j.operator=(operator+(i.operator++(), i.operator++()));
Let's call 'operator++' 'inc' and 'operator+' 'plus':
j.operator=(plus(i.inc(), i.inc()))
Both calls to 'i.inc()' are performed in unspecified order but (a) one
definitely returns before the other one is entered and (b) both are done
before 'plus' is entered. So, any side effects take place between all
sequence points and no object changes its value twice between sequence
points. And once 'plus' returns, its value is passed to operator=.
|
But I get a wrong result on three compilers: j == 6. (The compilers are
MSVC++ 7.1; Borland C++ 6.0 and Digital Mars 8.43).
I make an assumption that I have to consider modifications of object
_itself_ but not its members. Consequently there is an undefined
behaviour. However I am not sure about this assumption. Do you consider
that all three compilers are break?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron Natalie Guest
|
Posted: Thu Oct 20, 2005 5:31 pm Post subject: Re: UB and operator++() |
|
|
Maciej Sobczak wrote:
| Quote: | Vladimir wrote:
OK, that is a complete example:
#include
class MyClass
{
int i_;
public:
MyClass():i_(0) {}
MyClass(int i):i_(i) {}
MyClass& operator++(){++i_; return *this;}
friend MyClass operator+(MyClass& l, MyClass& r)
{
return l.i_ + r.i_;
}
};
int main ()
{
MyClass i = 1, j;
j = ++i + ++i;
}
I would like to know what's happening there. Thanks in advance.
Conceptually, the same as here:
MyClass i = 1, j;
++i; // i.i_ == 2 after this
++i; // i.i_ == 3 after this
j.i_ = i.i_ + i.i_; // j.i_ == 6 after this
The reason is that '+' in your example is an overloaded operator, which
is treated like a regular function in the sense that its parameters have
to be evaluated before this operator is executed. Here, evaluation of
parameters means executing ++i twice, but ++ is another operator, which
(again just like a regular function) is called twice. In this example,
it does not matter what is the order of calling ++ twice (and there is a
sequence point between them), so even if formally this is unspecified,
the result is always well-defined - but it's the math that gives you
this guarantee (for this particular example), not the language.
The REASON is that operator++ is overloaded. It means that the ++ |
operation is isolated by a function call and it's inherent sequence
points. If MyClass were a type that had a built-in ++ operator,
the behavior would be undefined regardless of the nature of the
+ operator, because it's possible both side effects would be applied
before hitting any sequence point implied by the overloaded + operators
call.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vladimir Guest
|
Posted: Thu Oct 20, 2005 5:34 pm Post subject: Re: UB and operator++() |
|
|
Maciej Sobczak wrote:
| Quote: | Conceptually, the same as here:
MyClass i = 1, j;
++i; // i.i_ == 2 after this
++i; // i.i_ == 3 after this
j.i_ = i.i_ + i.i_; // j.i_ == 6 after this
|
I'm sorry. I've thought the expression
| Quote: | MyClass i = 1, j;
j = ++i + ++i;
is equal to
j = 2 + 3 => == 5;
But I've overlooked a changing of both objects.  |
Thank you all for clarification.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Thu Oct 20, 2005 5:35 pm Post subject: Re: UB and operator++() |
|
|
Francis Glassborow wrote:
| Quote: | In article <21S4f.42107$Tf5.12729 (AT) newsread1 (DOT) mlpsca01.us.to.verio.net>,
Victor Bazarov <v.Abazarov (AT) comAcast (DOT) net> writes
Vladimir wrote:
Hello! Does this code lead to undefined behaviour, given that
operator++() is overloaded for MyClass?
MyClass i, j;
//...
j = ++i + ++i;
Unknown because you said nothing about whether operator+ was
overloaded for the result of operator++.
It seems unlikely that whether operator+ was overloaded would have any
influence. It might determine whether the code was well formed or not
(i.e. whether it would compile) but I doubt that undefined behaviour
would be an issue.
|
<Sigh>... Some of you seem to have made certain assumptions.
struct FUBAR {
FUBAR& operator++() { return *this; }
FUBAR operator+()(FUBAR const&) const {
return (this)[666];
}
};
int main() {
FUBAR a,b;
FUBAR c = ++a + ++b;
}
Compiles fine, don't it? The point I tried to make was that without
seeing the complete code, nothing could be said about its behaviour.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Thu Oct 20, 2005 5:35 pm Post subject: Re: UB and operator++() |
|
|
Vladimir wrote:
| Quote: | Victor Bazarov wrote:
I think it's the same as
cout << ++i << ++i;
The expression in question, rewritten in function terms, is
j.operator=(operator+(i.operator++(), i.operator++()));
Let's call 'operator++' 'inc' and 'operator+' 'plus':
j.operator=(plus(i.inc(), i.inc()))
Both calls to 'i.inc()' are performed in unspecified order but (a) one
definitely returns before the other one is entered and (b) both are done
before 'plus' is entered. So, any side effects take place between all
sequence points and no object changes its value twice between sequence
points. And once 'plus' returns, its value is passed to operator=.
But I get a wrong result on three compilers: j == 6.
|
Why do you think it's wrong? ++1 is 2, ++2 is 3, 3 + 3 is 6.
| Quote: | (The compilers are
MSVC++ 7.1; Borland C++ 6.0 and Digital Mars 8.43).
|
That's of no consequence. The result is correct and well-defined.
| Quote: | I make an assumption that I have to consider modifications of object
_itself_ but not its members.
|
I don't understand the difference. The object _is_ its members.
| Quote: | Consequently there is an undefined
behaviour.
|
No, there is not. There are sequence points between modifications. All
side effects take place at sequence points.
| Quote: | However I am not sure about this assumption. Do you consider
that all three compilers are break?
|
No, they are not "break". Your assumption is incorrect.
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|