1. ホーム
  2. c++

なぜOSごとにC/C++を再コンパイルする必要があるのですか?[重複あり]

2023-12-16 10:13:20

質問

これはどちらかというと理論的な質問です。私は、低レベルのプログラミングに大きな関心を持つ、コンピュータサイエンス専攻です。私は、ボンネットの下で物事がどのように動作するかを見つけることが大好きです。私の専門はコンパイラの設計です。

とにかく、最初のコンパイラーに取り組んでいるとき、ちょっと混乱するようなことが起こっています。

C/C++ でプログラムを書くとき、人々が知っている伝統的なことは、コンパイラが魔法のように C/C++ コードをそのマシン用のネイティブコードに変えてしまうということです。

しかし、ここで何か腑に落ちないことがあります。x86 アーキテクチャをターゲットとして C/C++ プログラムをコンパイルした場合、同じプログラムは同じアーキテクチャの任意のコンピューターで実行できるように思われます。しかし、そうはならない。OS X や Linux、Windows 用にコードを再コンパイルする必要があります (さらに 32 ビットと 64 ビットの場合にも再コンパイルが必要です)。

なぜこのようなことが起こるのか、不思議に思っています。C/C++ プログラムをコンパイルするとき、CPU アーキテクチャ/命令セットをターゲットにしないのでしょうか? そして、Mac OS と Windows OS は、まったく同じアーキテクチャで実行することができます。

(Java や類似のものが VM や CLR をターゲットにしていることは知っているので、これらはカウントされません)

もし私がこれでベストショットの答えを出したとしたら、C/C++ は OS 固有の命令にコンパイルされなければならないと言うでしょう。しかし、私が読んだすべてのソースは、コンパイラーはマシンをターゲットにしていると言っています。ですから、私は非常に混乱しています。

どのように解決するのですか?

<ブロッククオート

C/C++のプログラムをコンパイルするとき、CPUアーキテクチャ/命令セットをターゲットにしないのですか?

いいえ、そうではありません。

つまり、はい、あなたはCPU命令セット用にコンパイルしているのです。しかし、それは すべて コンパイルがすべてではありません。

最も単純な "Hello, world!" プログラムを考えてみましょう。このプログラムが行うのは printf を呼び出すだけですよね?しかし、"printf" 命令セットのオペコードはありません。では...一体何が起こるのでしょうか?

これはCの標準ライブラリの一部なんだ。その printf 関数は文字列とパラメータに対して何らかの処理を行い、そして...それを表示します。どうやって表示するんだ?それは、文字列を標準出力に送るからです。OK...誰がそれを制御するのですか?

オペレーティングシステムです。そして、quot;standard out"オペコードもありませんから、standard outに文字列を送るには、何らかの形でOSの呼び出しが必要です。

そして、OSコールはオペレーティングシステム間で標準化されていません。C や C++で独自に構築できなかったことを行う、ほとんどすべての標準ライブラリ関数は、少なくともその仕事の一部を行うために OS と話をすることになります。

malloc ? メモリはあなたのものではない、OSのものであり、あなたは もしかしたら を持つことが許されています。 scanf ? 標準入力はあなたのものではなく、OSのものであり、あなたはそこから読み取ることができるかもしれません。といった具合です。

標準ライブラリはOSのルーチンの呼び出しから構築されています。そして、これらのOSルーチンは移植不可能であり、したがって、標準ライブラリの実装も移植不可能である。そのため、あなたの実行ファイルには、これらの非ポータブルな呼び出しが含まれています。

そしてその上、OS によって "executable"が何であるかの考え方が異なります。 のように見えます。 . 結局のところ、実行可能ファイルは単なるオペコードの束ではありません。 static 変数はどこに保存されると思いますか?OS によって実行ファイルを起動する方法は異なりますし、実行ファイルの構造はその一部です。