[解決済み] 未定義の動作とシーケンスポイントの再読み込み
質問
このトピックは、次のトピックの続編であると考えてください。
前回の続き
未定義の動作とシーケンスポイント
これを再確認してみましょう。 面白い と 複雑な という表現があります(斜体のフレーズは上記のトピックから引用しています *smile* )。
i += ++i;
私たちは、これが未定義の振る舞いを呼び出すと言っています。このように言うとき、私たちは暗黙のうちに
タイプ
の
i
は組み込み型の一つです。
もし
型
の
i
はユーザー定義型ですか?その型が
Index
で、この記事の後半で定義されているとします(下記参照)。それはまだ未定義の振る舞いを呼び出すでしょうか?
もしそうなら、なぜですか?次のように書くことと同等ではありませんか?
i.operator+=(i.operator++());
と書くのと同じか、あるいは構文的にもっと単純な
i.add(i.inc());
? あるいは、それらも未定義の振る舞いを呼び起こすのでしょうか?
もしそうでないなら、なぜそうしないのでしょうか?結局のところ、オブジェクト
i
が変更されるからです。
2回
となります。経験則を思い出してください。
式がオブジェクトの値を変更できるのは、連続したシーケンスポイントの間で一度だけです。
. そして、もし
i += ++i
が式であるならば,それは未定義の振る舞いを呼び出さなければならない。もしそうであれば、その等価物である
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;
}
};
どのように解決するのですか?
次のようなコードです。
i.operator+=(i.operator ++());
シーケンスポイントに関しては全く問題なく動作します。 C++ ISO 標準のセクション 1.9.17 では、シーケンス ポイントと関数評価についてこのように説明されています。
関数を呼び出す場合 (関数がインラインであるかどうかにかかわらず)、すべての関数引数の評価後にシーケンス ポイントがあり、関数本体内の式やステートメントの実行前に行われます。また、戻り値のコピーの後、関数外の式の実行の前にもシーケンスポイントがあります。
これは、例えば
i.operator ++()
をパラメータとして
operator +=
はその評価の後にシーケンスポイントがあります。 つまり、オーバーロードされた演算子は関数であるため、通常のシーケンスルールが適用されます。
ところで、素晴らしい質問ですね。 すでに知っていると思っていた(と思っていた)言語のすべてのニュアンスを理解するよう私に強制しているところが本当に好きです :-)
関連
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] 未定義の動作とシーケンスポイント
-
[解決済み】なぜこれらのコンストラクトはプリインクリメントとポストインクリメントを使用して未定義の動作をしているのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】coutはstdのメンバではない
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] 未定義の動作とシーケンスポイント