このトピックを次のトピックの続編と考えてください。
前の記事
未定義の動作とシーケンスポイント
この面白くて複雑な表現をもう一度見てみましょう(イタリック体のフレーズは上記のトピック* smile *から取られています):
i += ++i;
これは未定義の振る舞いを引き起こすと言います。これを言うとき、私たちは暗黙のうちにタイプが組み込みタイプのi
1つであると仮定していると思います。
の型がi
ユーザー定義型の場合はどうなりますか?そのタイプはIndex
、この投稿の後半で定義されていると言います(以下を参照)。それでも未定義の振る舞いを呼び出しますか?
はいの場合、なぜですか?それは書くことと同等ではありませんi.operator+=(i.operator++());
か、あるいは構文的に単純 i.add(i.inc());
ですか?または、それらも未定義の振る舞いを呼び出しますか?
いいえの場合、なぜですか?結局のところ、オブジェクトi
は連続するシーケンスポイント間で2回変更されます。経験則を思い出してください。式は、連続する「シーケンスポイント間でオブジェクトの値を1回だけ変更できます。また、i += ++i
が式の場合 、undefined-behaviorを呼び出す必要があります。その場合、同等のものi.operator+=(i.operator++());
で i.add(i.inc());
あり、undefined-behaviorも呼び出す必要があります。真実ではないようです!(私が理解している限り)
または、i += ++i
そもそも表現ではないですか?もしそうなら、それは何ですか、そして表現の定義は何ですか?
それが式であると同時に、その動作も明確に定義されている場合、式に関連付けられているシーケンスポイントの数は、式に含まれるオペランドのタイプに何らかの形で依存することを意味します。私は(部分的にでも)正しいですか?
ちなみに、この表現はどうですか?
//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.
応答でもこれを考慮する必要があります(その動作を確実に知っている場合)。:-)
です
++++++i;
C ++ 03で明確に定義されていますか?結局のところ、これはこれです、
((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;
}
};