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