Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

C++とかC#とか数学ネタを投下していく予定です。

[その他のページ]
日々の四方山話を綴った日記出水の日記帳

書庫

日記カテゴリ

[C][C#]あれとは違うこれ

ネタ元>ちょっとしたクイズです

Rさんが問題を出していますが…実はこれ、根が深いですよ…。

ということで、私も問題。
言語はC#です。

int i;
i = 0; var a = i * i++;
i = 0; var b = i * ++i;
i = 0; var c = i++ * i;
i = 0; var d = ++i * i;

a, b, c, dの値を答えてください。

C言語とC#だと結果が変わってきます。
それに、C言語の場合、i = i * i++; と書いてしまうと未定義動作です。

この動作は、C# だとどうなっているのか調べてみました。

7.2 演算子 (C#)

>式のオペランドは、左から右に評価されます。
>これは、演算子の優先順位とは異なるものであり、関係ありません。

つまり、前置インクリメントであれ、後置インクリメントであれ、
インクリメントの左にある場合は古い値、右にある場合は新しい値として評価されます。

そして、i *= 10;のような複合代入の場合です。
これは、i = i * 10; と展開されるため、常に古い値として評価された値との演算になります。
結果的に想定通りの答えだとしても、意外に難しい問題です。

また、調べていたらこんなものを発見しました。

7.4.1 引数リスト (C#)

こちらで紹介されているサンプルソースです。

var i = 0;
foo (i++, i++, i++);

これも、C言語ではやはり未定義と呼ばれているものですね。
C言語だと、引数の順序をどのように評価してもいいし、またi++が3回呼ばれるかどうかすら定かではありません。

しかし、C#は正確に前から評価していくみたいなので、この呼び出しは、foo(0, 1, 2); と等価なのだそうです。
この関数を呼び終わった後のiの値は、当然3です。

このあたりのC言語では未定義だったゾーンがC#ではきっちりきまっているみたいです。

投稿日時 : 2009年6月15日 22:09

Feedback

# re: [C][C#]あれとは違うこれ 2009/06/16 0:00 えムナウ

>そして、i *= 10;のような複合代入の場合です。
>これは、i = i * 10; と展開されるため、常に古い値として評価された値との演算になります。

表現としては正しいんだけども言語仕様にもあるように、x op= y は x = (xの保存した値) op y で y でどんなに x を変化させようが xの保存した値 が利用されます。

~~~~~~~~

C# 言語仕様 Version 3.0 7.16.2 複合代入(抜粋)
?選択された演算子の戻り値の型を x の型に "暗黙に" 変換できる場合は、演算は x = x op y として評価されます。ただし、x は 1 回だけ評価されます。

"1 回だけ評価される" とは、x op y の評価において、x を構成するすべての式の結果は一時的に保存されて、x への代入を実行するときに再利用されることを意味します。

# re: [C][C#]あれとは違うこれ 2009/06/16 0:02 n

a = 0
b = 0
c = 0
d = 1

>これがC言語だとするとどうにも気持ち悪いのが、インクリメント演算子と代入の同時使用。
>こんな式を書くと、C言語なら未定義という用語が使われています。

c/c++ でも未定義でないと思う。
結果をiに代入してたら未定義だけど・・・
(1つ副作用完了点までに、2回以上変更されては駄目みたいなやつです。)

# re: [C][C#]あれとは違うこれ 2009/06/16 0:07 えムナウ

>C# 言語仕様 Version 3.0 7.16.2 複合代入(抜粋)
出水さんの引用サイトからだとここですね。
7.13.2 複合代入
http://msdn.microsoft.com/ja-jp/library/aa691316(VS.71).aspx

# re: [C][C#]あれとは違うこれ 2009/06/16 8:00 出水

>えムナウさん
ここは、i = 10 * i;と展開されないって意味でした。

>nさん
もともと i = i * i++;だったんですけど
いじっている最中に消えちゃいましたね…
ちょっと修正しました

# ohrdxACymtxcHNWL 2011/12/22 19:29 http://www.discreetpharmacist.com/

yS1Bco I am getting married on the 15th of November. Congratulate me! Then will be here rarely!...

# maQSSlqUuoIMk 2012/01/07 9:20 http://www.luckyvitamin.com/m-191-now-foods

The text is promising, will place the site to my favorites..!

タイトル
名前
Url
コメント