- - PR -
intは何でできてるの?
投稿者 | 投稿内容 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2002-05-24 19:50
↓これのことですよね?
どう読んでも日本語訳どおりにしか読めません。intはSystem.Int32のエイリアスです。
はっきり言います。コンパイルできません。C#言語仕様に、intはSystem.Int32のエイリアスだと書いてある以上、System.Int32を提供しないシステム上にC#言語を実装することはできません。C#コンパイラがintに出くわしたときにどんなコードを吐き出せばいいのか、そのルールがないからです。もしこれがコンパイルできるなら、それはC#ではありません。 | ||||||||||||||||||||
|
投稿日時: 2002-05-25 00:15
確かにそうですね さっきわたしが記事を投稿した後に、NothingBut.NETFXさんの「C#には型システムは存在しない」という言葉を思い出しました。もし、System name spaceの中にInt32が存在しなかったら、C#の文法にあるintというのは「キーワード」としては存在するけれど、型としては機能しないということに気がつきました。また、intというキーワードがSystem.Int32のエイリアスというのは、C#のコンパイラが「ソースにintが来たらSystem.Int32にする」という固定のルールがあって、別にtypedefのような文で定義しなおしてはいないとこうことも分かりました。 intの謎を解く鍵は、
ですね ところで更にお聞きしたいのですが、int32.csの
がどのような手順でコンパイルされるのか教えてもらえますか? | ||||||||||||||||||||
|
投稿日時: 2002-05-25 00:48
すえぞうさん、私が言いたかった事が十分伝わって無いように感じたので、補足します。 私は、上の例をみても分かる通り、「Int32」は「int」で定義されていると考えています。 何故この様な定義が必要なのでしょうか? 私は、つまりこの時点では、「Int32」は存在しないからこそ、「int」で定義していると考えます。 前にも書きましたが、「Int32」を実装しているC#と、「Frame Work」上のC#を同じC#とは考えない方が良いのじゃないでしょうか? 私は、そう考えています。 | ||||||||||||||||||||
|
投稿日時: 2002-05-25 11:55
えっと、もちろん私はC#コンパイラの実装者ではありませんのでホントのところはわかりません。以下は想像(とILDASMの出力)に過ぎません、念のため。
上記の型をコンパイルすると、C#コンパイラは次のようなCILコードを出力します。
さらに、これらを利用する次のようなC#コードをC#コンパイラでコンパイルすると、
次のようなCILコードが出力されます。
文字列や整数を扱うコードと、構造体を扱うコードの違いに注目してください。前者はstringやint32などの、ilasmアセンブリ言語の型の値を扱っているのに対して、後者はvaluetype Sという形でメタデータへの参照を行っています。これが、CLRが型についての情報を知っているか知らないかの違いです。 intがSystem.Int32のエイリアスであるという事実は、そこで止まってしまっては理解できないのです。さらに、System.Int32のボックス化されていない形式が、CLRが内部的に持っているint32という型にマップされるという事実まで踏み込まなければなりません。 さらに言うと、値型にはボックス化形式とボックス化されていない形式があることも理解しなければなりません。値型を宣言すると、その「値」の部分、つまりフィールド部分だけがスタック上に確保されるようなイメージになります。System.Int32のフィールドはm_valueだけですから、System.Int32を確保しようとすると、スタック上にm_valueの領域を確保しようとします。ここでもしm_valueの型(System.Int32==int32)の情報をCLRが知らなければ、CLRはメタデータを見て必要なサイズを知ります。ですが、この場合はCLRはサイズを知っていますから、問題なくスタック上に32ビットの領域を確保して、それを0で初期化することができるのです。 | ||||||||||||||||||||
|
投稿日時: 2002-05-25 15:03
ソースコードを素直に読めば、そういう読みとれますね。 余談ですが、
はどちらも、まったく同じアセンブラコードを吐き出します。 そのことから考えると、おそらくC#コンパイラはintとSystem.Int32が等価であることを知っていて、処理に区別をしていないと思います。それに対して、アセンブラレベルでのint32とSystem.Int32は異なる役割を持っていて、使い分けられているように見えます。たとえばi=0ならint32だけで処理できますが、ToString()メソッドを呼ぶと、System.Int32を参照するコードが生成されます。 ですので、根拠はありませんが、以下のような状況なのかもしれません。 ・ C#コンパイラは、intとSystem.Int32が等価であることを知っている ・ C#コンパイラは、intとSystem.Int32が32bit符号付き整数であることを知っている ・ C#コンパイラは、System.Int32の構造体定義(どんなメソッドがある等)は知らない ・ C#コンパイラは、どちらの型もアセンブラのint32で扱おうとする ・ C#コンパイラは、int32で扱えない状況に出会ったら構造体定義を参照する すると、System.Int32の定義が存在しない状況でも、System.Int32の構造体定義を参照しない限り、intはコンパイル可能となります。 また、C#コンパイラは、intとSystem.Int32が等価であることを知っているだけで、System.Int32の定義を内部に持っているわけではないので、C#コンパイラ外部でSystem.Int32を定義しても二重定義になりません。 繰り返しますが、これが本当かどうかは知りませんよ。
そう思います。 言語仕様で要求されるライブラリをビルドするのに、それ自身の処理系を使う場合がありますが、当然その段階では、言語仕様を満たしていない状態で走ることになります。 | ||||||||||||||||||||
|
投稿日時: 2002-05-27 01:33
全く唐突で、なにやらわからないと思いますが、autumnさん、NothingBut.NETFXさん、解説ありがとうございました。おかげで、間違いを修正できました(ちょっと遅きに失したけど)。
[ メッセージ編集済み 編集者: arton 編集日時 2002-05-27 01:45 ] | ||||||||||||||||||||
|
投稿日時: 2002-05-27 10:59
大変、興味深い解説、ありがとうございます。
ちょっと話が戻りますが、
int32.csをコンパイルする時点では、C#という言語は仕様は満たしてはいないけれども、コンパイルは可能ということですね。ということは、System.Int32が、もし、実装されていない場合、 int i; i = 0; をコンパイルすると、コンパイラは「int」をILの「int32」にコンパイルするということでしょうか? autumnさんのいう通り、「int==System.int32」というように等価と考えれば、そうなると思います。 ということは、わたしが今まで考えていた、 C#の「int」キーワード → CLRの「System.Int32」にマッピング → ILの「int32」を出力 ではなく、 C#の「int」キーワード → ILの「int32」を出力 CLRの「System.Int32」 → ILの「int32」を出力 ということになると思います。この考えは正しいですか? C#のコンパイラと.NET Frameworkのコンパイラが同じものだとは限らないということは、承知しているのですが・・・どうなんでしょね〜、気になります。 #何かあったのですか? (^^; > artonさん #このスマイリーって書き方悪いですか?アイコンに変換されません → (^^; | ||||||||||||||||||||
|
投稿日時: 2002-05-27 12:00
すえぞうさん、autumn、NothingBut.NETFX御二人それぞれ、C#の「内部処理」に関するとてもデリーケートな話をしてた訳ですよ! 内部処理という事をもっと理解すべきだと思います。 大切な事ですが、 「int」=「System.Int32」 これは、基本的です。 ただ、内部的に問題が無い限り、C#が「int」を「Integer」として処理しているという事だと思います。 それで、全てを理解すべきだと思います。 (「int」はC#にとってプリミティブなんです!) それから、
ですが、autumnさん、NothingBut.NETFXさんそれぞれ異なる見解ですが、これは仕様の問題です! C#の本来の仕様からいけば、これは出来ないと思います。(C#はInt32の存在が前提ですから!) でも、技術者は、基本的にはこれを処理出来るように作るでしょう!(間違いとする場合は、チェックしてハジクだけ!) (「前提が誤ってる時、結果は正誤どちらも場合も正しい。」:これは、記号論理的には正です!) |