左と右の話
Upcoming SlideShare
Loading in...5
×
 

左と右の話

on

  • 451 views

左辺値と右辺値の話

左辺値と右辺値の話

Statistics

Views

Total Views
451
Views on SlideShare
318
Embed Views
133

Actions

Likes
5
Downloads
1
Comments
0

1 Embed 133

https://twitter.com 133

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

左と右の話 左と右の話 Presentation Transcript

  • 2014/9/20 Cryolite Boost.勉強会#16 大阪 1 左と右の話
  • 左と右の区別は大事です
  • 3 左と右の区別は大事です
  • 4 左と右の区別は大事です ※画像はイメージです
  • 5 左と右の区別は大事です (※大事なことなので以下略)
  • 6 左と右の区別は大事です (※大事なことなので以下略)
  • 7 左と右の区別は大事です (※大事なことなので以下略)
  • 左と右の区別は大事です (※大事なことなので以下略) ※画像はあくまでイメージです8
  • 9 C++で大事な左と右と言えば?
  • 10 C++で大事な左と右と言えば? i = 42; 左辺値右辺値
  • 11 左辺値・右辺値とは何か? i = 42; 左辺値右辺値 式の値を格納した場所 Cf. “Location value” 式の値
  • i int &f(); f() 全て規格に 12 左辺値・右辺値とは 全ての式がおのおの持つ属性 左辺値となる式 右辺値となる式 42, i + j int g(); g() MyClass(arg) 書いてある
  • 13 代入演算子における 左辺値・右辺値の例 i = 42; 変数“i” からなる式 “i” の値を格納した場所(左辺値)
  • 14 代入演算子における 左辺値・右辺値の例 i = 42; リテラル“42” からなる式 “42” の値(右辺値)
  • 15 代入演算子における 左辺値・右辺値の例 i = 42; “i” という式の値を格納した場所 (左辺値)に, “42” という式の値 (右辺値)を代入する
  • 16 代入演算子における 左辺値・右辺値の例 i = 42; “i = 42” という式の値を 格納した場所(左辺値)
  • 17 代入演算子の右辺に 左辺値が来たらどうなるの?
  • 18 代入演算子の右辺に 左辺値が来たらどうなるの? j = i
  • 19 代入演算子の右辺に 左辺値が来たらどうなるの? j = i “j” という式の値を格納した場所 (左辺値)に, “i” という式の値を 格納した場所(左辺値)を代入する?
  • 20 代入演算子の右辺に 左辺値が来たらどうなるの? j = i “j” という式の値を格納した場所 (左辺値)に, “i” という式の値を 格納した場所(左辺値)を代入する?
  • 21 代入演算子は 右辺に右辺値が欲しい!
  • 22 代入演算子は 右辺に右辺値が欲しい! =
  • 23 代入演算子は 右辺に右辺値が欲しい! = 右辺には右辺値が欲しい
  • 24 代入演算子は 右辺に右辺値が欲しい! = 右辺には右辺値が欲しい 左辺には左辺値が欲しい
  • 25 代入演算子は 右辺に右辺値が欲しい! 左辺に期待通り左辺値が来た!問題無し! j =
  • 26 代入演算子は 右辺に右辺値が欲しい! 右辺に右辺値が欲しいのに左辺値が来た! 欲しいのと違う! j = i
  • 27 代入演算子は 右辺に右辺値が欲しい! 右辺に右辺値が欲しいのに左辺値が来た! 欲しいのと違う! j = i 左辺値を右辺値として解釈しなおそう!
  • 28 代入演算子は 右辺に右辺値が欲しい! 右辺に右辺値が欲しいのに左辺値が来た! 欲しいのと違う! j = i 左辺値を右辺値として解釈しなおそう! j = i
  • 左辺値から 右辺値への変換 lvalue-to-rvalue 29 代入演算子は 右辺に右辺値が欲しい! 右辺に右辺値が欲しいのに左辺値が来た! 欲しいのと違う! j = i 左辺値を右辺値として解釈しなおそう! j = i conversion
  • 値が格納された場所(左辺値) から値(右辺値)を取り出す 左辺値から 右辺値への変換 lvalue-to-rvalue 30 代入演算子は 右辺に右辺値が欲しい! 右辺に右辺値が欲しいのに左辺値が来た! 欲しいのと違う! j = i 左辺値を右辺値として解釈しなおそう! j = i conversion
  • “j” という式の値を格納した場所 (左辺値)に, “i” という式の値 (右辺値)を代入する 左辺値から 右辺値への変換 lvalue-to-rvalue 31 代入演算子は 右辺に右辺値が欲しい! j = i j = i conversion
  • 他の組み込み演算子, statement 等は左右どちらが欲しい?
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? 33 R + R
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? 34 R + R -R
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? 35 R + R -R &L
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? R + R -R &L L = R 36
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? R + R -R &L L = R int i = R; 37
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? R + R -R &L L = R int i = R; int &ri = L; 38
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? R + R -R &L L = R int i = R; int &ri = L; if (R) {… 39
  • 他の組み込み演算子, statement 等は左右どちらが欲しい? R + R -R &L L = R int i = R; 全て規格に int &ri = L; 書いてある if (R) {… 40
  • 41 式の左辺値・右辺値に 関する2つの視点
  • ある式が,出現する文脈で左辺値・右辺値の 42 式の左辺値・右辺値に 関する2つの視点 式自身が左辺値なのか右辺値なのか i 42 どちらであることを要求されるのか 左辺値が欲しい= 右辺値が欲しい
  • 43 式の左辺値・右辺値に関する 2つの視点とL-to-R 変換 ある式が左辺値 である 右辺値 である 出現して いる文脈 で 左辺値である ことが要求さ れている そのま まで O.K. コンパ イルエ ラー 右辺値である ことが要求さ れている L-to-R 変換が 起きる そのま まで O.K.
  • 44 式の左辺値・右辺値に関する 2つの視点とL-to-R 変換 ある式が左辺値 である 右辺値 である 出現して いる文脈 で 左辺値である ことが要求さ れている そのま まで O.K. コンパ イルエ ラー 右辺値である ことが要求さ れている L-to-R 変換が 起きる そのま まで O.K. &42 42=0
  • 45 全ては規格のシナリオ通りに
  • 46 全ては規格のシナリオ通りに • 式自身が左辺値か右辺値か ⇒全て規格に書いてある
  • 47 全ては規格のシナリオ通りに • 式自身が左辺値か右辺値か ⇒全て規格に書いてある • 個々の文脈で式に左辺値・ 右辺値のどちらが要求されるか ⇒全て規格に書いてある
  • 48 全ては規格のシナリオ通りに • 式自身が左辺値か右辺値か ⇒全て規格に書いてある • 個々の文脈で式に左辺値・ 右辺値のどちらが要求されるか ⇒全て規格に書いてある • いつ左辺値から右辺値への 変換が起きるか ⇒全て上2つから判断できる
  • 左辺値から右辺値への変換が 起きる場所は全て規格に書いてある 49
  • 左辺値から右辺値への変換が 起きる場所は全て規格に書いてある 50
  • 全てのコーナーケースは 左辺値から右辺値への変換に通ず 51
  • 全てのコーナーケースは 左辺値から右辺値への変換に通ず 52
  • 例:オブジェクトが未構築な 領域にどんな操作が許されるか? 53
  • 例:オブジェクトが未構築な 領域にどんな操作が許されるか? 54 オブジェクトに対して左辺値から 右辺値への変換が起きたらアウト void *p = std::malloc(sizeof(int int &ri = *p; セーフ &ri; ri + 1; アウト int *pi = new (p) int(42);
  • 55 例:未初期化な変数に どんな操作が許されるか?
  • 56 例:未初期化な変数に どんな操作が許されるか? 変数に対して左辺値から右辺値への 変換が起きないようにすればセーフ void f(int &); void g(int); int i; f(i); セーフ g(i);アウト
  • 57 例:型の完全な定義が いつ必要になるか?
  • 58 例:型の完全な定義が いつ必要になるか? 左辺値から右辺値への変換が起きた オブジェクトの型は完全でなければならない class X; void f(X &x) { セーフ &x; static_cast<X>(x); セーフ } アウト
  • 59 例:変数の定義がいつ必要に なる(odr-usedされる)か?
  • 60 例:変数の定義がいつ必要に なる(odr-usedされる)か? 変数がコード中に出現すればodr-used ただし,変数がconstant expression であり 即座にL-to-R 変換が起きる場合は対象外 Template<typename T> struct X { static constexpr int i = 42; }; i + 1; std::cout << i << std::endl; アウト セーフ
  • xvalue, prvalue, glvalue の話はどこに行った?
  • xvalue, prvalue, glvalue の話はどこに行った? 現在のC++ の左辺値・右辺値の 区別は実は3種類 • lvalue • xvalue • prvalue
  • xvalue, prvalue, glvalue の話はどこに行った? “Location” の 意味を持つか 寿命が短い lvaue Yes No xvalue Yes Yes prvalue No Yes
  • xvalue, prvalue, glvalue の話はどこに行った? “Location” の 意味を持つか 寿命が短い lvaue Yes No xvalue Yes Yes prvalue No Yes 今日の発表の 左と右の境界
  • xvalue, prvalue, glvalue の話はどこに行った? “Location” の 意味を持つか 寿命が短い lvaue Yes No xvalue Yes Yes prvalue No Yes move semantics, 右辺値参照で 重要な左と右の境界
  • まとめ: • 左辺値とは何か,右辺値とは何か • 左辺値から右辺値への変換とは何か,それは いつ起きるのか • 左辺値から右辺値への変換がいつ起きるのか は様々なコーナーケースでの判断に重要 • 左辺値と右辺値の区別はmove semantics, 右辺値参照の話でも重要だが,本発表での左 辺値と右辺値の区別の場合と境界線が異なる 66