- PR -

intは何でできてるの?

投稿者投稿内容
NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-05-27 12:07
引用:

すえぞうさんの書き込み (2002-05-27 10:59) より:
int32.csをコンパイルする時点では、C#という言語は仕様は満たしてはいないけれども、コンパイルは可能ということですね。


そんなことないのでは?C#の言語仕様にはintがSystem.Int32とイコールであると書かれているだけです(その結果として32ビットの整数値であるとは書いてあるけど)。C#コンパイラの役割は、System.Int32 i = 0;というコードをldc.i4.0というILに変換することであって、それ以上でも以下でもありません。このルールだけでInt32.csをコンパイルできるはずです。言語仕様を満たさないコンパイラ云々というところまで曲解しなくても説明できてると思います。

もしかしてSystem.Int32が持っているToStringなどのメソッドが気になっているのかもしれませんが、CTSによって値型は継承できず継承されないと定義されていますから、System.Int32が直接持っているメソッド(ToStringなど)に対する呼び出しはコンパイラがメタデータを見ればstaticに解決できます。実行時情報を必要としないので、ILに直接呼び出しが出力されるわけです。ですが、この話はInt32.csがコンパイルできるかどうかとは関係ありません。

引用:

int i;
i = 0;

をコンパイルすると、コンパイラは「int」をILの「int32」にコンパイルするということでしょうか?


そういうことになります。ただし、intをint32に変換するという意味ではありません。intをint32として扱うという意味です。ですから、上記のコードはldc.i4.0というILになります。

引用:

ということは、わたしが今まで考えていた、

C#の「int」キーワード → CLRの「System.Int32」にマッピング → ILの「int32」を出力

ではなく、

C#の「int」キーワード → ILの「int32」を出力
CLRの「System.Int32」 → ILの「int32」を出力


ん?なぜそうなりますか?C#のintはイコールSystem.Int32ですから、CLRの、とかC#の、とかいう違いはありませんよ?

おそらく「マッピング」というのが混乱の下だと思います。intとSystem.Int32は「まったく同じもの」です。C#のintをCTSのSystem.Int32にマッピングするのではありません。intがSystem.Int32そのものなんです。System.Int32を宣言し、値を設定するときの方法は、CLRがすでに知っています。ldc.i4命令です。ですから、各言語のコンパイラはそれを吐き出せばいいのです。System.Int32がメソッドをいくつ持っているかなんてことは、System.Int32 i = 0;というコードをコンパイルするときには全然評価の対象になりません。これはCLRがそれをする必要がないことを「知っている」からです。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-05-27 12:51
引用:

NothingBut.NETFXさんの書き込み (2002-05-27 12:07) より:

おそらく「マッピング」というのが混乱の下だと思います。intとSystem.Int32は「まったく同じもの」です。C#のintをCTSのSystem.Int32にマッピングするのではありません。intがSystem.Int32そのものなんです。


もし、「マッピング」という言葉がすえぞうさんに影響を与えているのなら、私の責任ですね!(これは私が使いましたから。)
すえぞうさん、済みません! 

少しこの言葉を使った、私の考えを少し具体的に説明します。

C#の仕様(外部的)
intは「System.Int32」のエイリアス。

C#の内部
intは「System.Int32」と「Integer相当プリミティブ」で対応。

このC#が、元から持っている「Integer相当プリミティブ」に対する機能を補足する「System.Int32」に対する動作・機能を私はマッピングと呼びました。

少しでも、すえぞうさんの理解に役立てばと思います。
Muse
常連さん
会議室デビュー日: 2002/03/08
投稿数: 34
投稿日時: 2002-05-27 15:10
真剣な解説、ありがとうございます。
理解するのに苦しんでいます。頭が悪いので、もう少しだけお付き合いください。
引用:

そんなことないのでは?C#の言語仕様にはintがSystem.Int32とイコールであると書かれているだけです(その結果として32ビットの整数値であるとは書いてあるけど)。C#コンパイラの役割は、System.Int32 i = 0;というコードをldc.i4.0というILに変換することであって、それ以上でも以下でもありません。このルールだけでInt32.csをコンパイルできるはずです。言語仕様を満たさないコンパイラ云々というところまで曲解しなくても説明できてると思います。


int32.csには「int」というキーワードでm_valueが定義されています。この「int」というキーワードは、CLRは理解するのでしょうか?
つまり、ソース中にint i; i = 0; に出くわしたときに、CLSではSystem.Int32はldc.i4.0に変換するというのは分かりますが、intはCLSではないので、intをSystem.Int32とみなすステップが、コンパイルの過程でどこかにあるのかなと思ったのです。
うまく言葉にできないのですが、intとSystem.Int32がイコールであるといのが、どのレベルでの話なのかが、まだ、理解できていません。
NothingBut.NETFX
大ベテラン
会議室デビュー日: 2001/09/13
投稿数: 102
投稿日時: 2002-05-27 16:01
うむー、私の解説がへたくそなんですよね。。すみません。

引用:

すえぞうさんの書き込み (2002-05-27 15:10) より:
intをSystem.Int32とみなすステップが、コンパイルの過程でどこかにあるのかなと思ったのです。


intをSystem.Int32とみなすステップは、C#コンパイラのコンパイル作業におけるもっとも初期のステージに存在すると考えればいいでしょう。つまり、C#コンパイラはソースコードが与えられると、まずC#固有のキーワードをすべて対応するCTSの型に置き換えます。それからコンパイル処理を始めます。たとえば、int i = 0;というソースを、まずSystem.Int32 i = 0;に置き換え、それからそのコードをコンパイルしてILに変換します。

CLRはILを実行します。ILになっている時点(つまりコンパイル後)で、C#のintは影も形もなくなります。同様に、この場合はSystem.Int32も影も形もなくなります。あるのは、32ビット整数リテラルである0をスタックにロードし、それをローカル変数iに格納するというILコードだけです。

引用:

int32.csには「int」というキーワードでm_valueが定義されています。この「int」というキーワードは、CLRは理解するのでしょうか?


というわけで、理解しない、というのが回答になります。

C#のソースコードであるintを、CLRが理解するCILに変換するのがC#コンパイラの仕事です。C#コンパイラは実行可能コードを出力するわけではなく、CILという別のプログラミング言語のソースコードを出力するだけです。CILプログラミング言語のコンパイラは、CLRにJITterという形で備わっています。JITterがint32が何を意味しているのかを理解すればいいのです。ですから、intがSystem.Int32であるときに、その定義の中にintが含まれていても問題ありません。C#はintを解釈しないからです。intというのは単なるキーワード、ブックマークのような存在に過ぎません。
Muse
常連さん
会議室デビュー日: 2002/03/08
投稿数: 34
投稿日時: 2002-05-27 17:01
詳細な解説、ありがとこございます。大変、興味深い議論でした。
これで「鶏が先か?卵が先か?」の謎が全てとけたと思います。
intひとつをとっても、これだけ議論ができるC#という言語は不思議な言語ですね。

スキルアップ/キャリアアップ(JOB@IT)