Consider this topic a sequel of the following topic:
Previous installment
Undefined behavior and sequence points
Let's revisit this funny and convoluted expression (the italicized phrases are taken from the above topic *smile* ):
i += ++i;
We say this invokes undefined-behavior. I presume that when say this, we implicitly assume that type of i
is one of the built-in types.
What if the type of i
is a user-defined type? Say its type is Index
which is defined later in this post (see below). Would it still invoke undefined-behavior?
If yes, why? Is it not equivalent to writing i.operator+=(i.operator++());
or even syntactically simpler i.add(i.inc());
? Or, do they too invoke undefined-behavior?
If no, why not? After all, the object i
gets modified twice between consecutive sequence points. Please recall the rule of thumb: an expression can modify an object's value only once between consecutive "sequence points. And if i += ++i
is an expression, then it must invoke undefined-behavior. If so, then its equivalents i.operator+=(i.operator++());
and i.add(i.inc());
must also invoke undefined-behavior which seems to be untrue! (as far as I understand)
Or, i += ++i
is not an expression to begin with? If so, then what is it and what is the definition of expression?
If it's an expression, and at the same time, its behavior is also well-defined, then it implies that the number of sequence points associated with an expression somehow depends on the type of operands involved in the expression. Am I correct (even partly)?
By the way, how about this expression?
//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the subscript operator!
a[++i] = i; //Taken from the previous topic. But here type of `i` is Index.
You must consider this too in your response (if you know its behavior for sure). :-)
Is
++++++i;
well-defined in C++03? After all, this is this,
((i.operator++()).operator++()).operator++();
class Index
{
int state;
public:
Index(int s) : state(s) {}
Index& operator++()
{
state++;
return *this;
}
Index& operator+=(const Index & index)
{
state+= index.state;
return *this;
}
operator int()
{
return state;
}
Index & add(const Index & index)
{
state += index.state;
return *this;
}
Index & inc()
{
state++;
return *this;
}
};
s
is user-defined type!) – Nawaz