web-dev-qa-db-ja.com

Cは「低水準」言語としてどの程度「低」になりますか?

Cは低水準言語だとよく耳にしますが、どれくらい低くなるのでしょうか。私が知っている最低レベルは、ポインタを使用したメモリ管理です。私がまだ発見していないさらなるレベルはありますか? 「ハードウェアに近い」とはどういう意味ですか? Cはどのくらい「ハードウェアに近い」のですか?

23

標準の用語を使用します。高水準言語と低水準言語。

高水準言語は、言語を書く人が簡単に使えるように設計されています。

低水準言語は、コンピューターがその言語を実行しやすいように設計されています。

Cは、実際には機械語の人間による翻訳であるアセンブリ言語からの一歩です。機械語より低くなることはありませんが、16進数はあまり読めないため、アセンブリは最低レベルのプログラミング言語と見なされます。

ほとんどのC演算は、10未満のマシン命令に変換できます。一部は(多くの状況に応じて)単一のマシン命令に変換できます。比較すると、多くの高級言語では、特定の操作を実装するために数十から数千のマシン命令が必要になる場合があります。

言語の「レベル」は、ほとんどが抽象的な概念です。どちらかでより多くのソースコードを書く必要があるかどうか、または比較して1つの言語でマシンのアーキテクチャについてもっと知る必要があるかどうかを理解しようとする文脈で、ある言語を別の言語と比較する以外には、あまり役に立ちません。別のものに。

24
Edwin Buck

Cは、ASMの手続き型ラッパーにすぎません。その言語の背後にあるものを知っている優れたCプログラマーは、コードスニペットを見て、コードがコンパイルされるASMを書き出すことができるはずです。これらのASM命令は、1:1でバイナリマシン命令に変換できます。これはアセンブリのほぼ1ステップ上にあり、コンピュータが実行できるすべてのことを実行するCコードを記述できますが、レベルが非常に低いため、具体的に何を指定する必要があるかという点では比較的原始的です。たとえば、メモリはそのように扱われ、「ヒープ」のような構造に抽象化されません。 OO言語で「新しい」オブジェクトを作成するのは、そう言うのと同じくらい簡単です。同等のCコードには、そのオブジェクトのすべてのメンバーのサイズの合計のmallocとポインターが含まれます。ブロック内のオブジェクトの各メンバーに。

6
KeithS

Cは「ポータブルアセンブリ言語」と呼ばれることもあります。基本的に、アセンブリで実行できることはすべて、Cで実行できます(言語に組み込まれた機能またはインラインアセンブリを介して)。

5
bta

ハードウェア(CPU、マザーボードなど)を作成する人は、その機械語(アセンブリ言語)も提供します。それ自体が最低レベルになります。次に、他の誰かがCのコンパイラを作成し、C構文をそのハードウェアのネイティブアセンブリ言語に変換します(間違っている場合は修正してください)。 Cを使用すると、アセンブリを使用できるため、最低レベルに到達します。

4
Mr Coder

'low'の定義は少し難しいですが、Cは多くのシステムコール、goto、さらには拡張機能を介したアセンブリミキシングをサポートしています。

2
Kevin Sylvestre

汎用OSで管理できるメモリは通常 仮想メモリ であるため、通常はすべて詐欺です。Cポインタには物理メモリアドレスが含まれておらず、それよりも深い層があります。

それを下回るには、 [〜#〜] mmu [〜#〜] をプログラムする必要があります。これは、Cでは簡単に実行できません。通常、アーキテクチャに非常に依存するアセンブリが必要であり、コードで次のことを行う必要があります。何らかの形の特権で実行 モード (OSカーネルのように)

他にもさまざまな コプロセッサー または 命令セット の全範囲が存在する可能性があります。Cで直接取得するのは難しい場合があります。

2
nos

この質問に答えるには、低レベルの意味を定義する必要があります。

Cを使用すると、アセンブリで実行できるすべてのことを実行できますが、すべてではありません。奇妙な/特定の/異常なことをしたい場合は、アセンブリを使用する必要がありますが、ハードウェアに適したコンパイラがあれば、ほとんど(/すべて?)の実際の目的ではCで十分です。


[〜#〜] edit [〜#〜]:これをもう少し詳しく説明します...

Cは、コンパイルされるアセンブリ命令については保証せず、メモリに割り当てられるオブジェクトについての部分的な指示のみを提供します。

一般に、特定の方法でメモリにデータを格納する必要がある場合、またはアセンブリ命令の特定のシーケンスを実行する必要がある場合は、おそらく他の言語(おそらく直接アセンブリ)を使用する必要があります。それ以外の場合は一般的に Cで問題ありません。

もちろん、必要な数の特殊なケースを見つけることができます。派手な高レベルのものを実行できる特別なアセンブリ操作がある場合は、Cおそらくこれらを悪用することはできません。

Cはnormalのアセンブリを置き換えると考えられています(多分私は汎用)プロセッサ、ネイティブ機能アセンブリを備えたプロセッサや他の多くのコンテキストでは理想的ではありません。


「Cのレベルはどれくらいですか?」とだけ言うことはできません。反対のことをする必要があります。必要な低レベルのものの種類を定義してから、 Cはそれを行うことができます。

2
peoro

今日のCは、多くの場合、「ポータブルアセンブリ言語」として使用されています。これは、言語のセマンティクスが、基盤となるマシンアーキテクチャの上の薄いベニヤにすぎないためです。

以前は、Cコードの行を見て、Cコードが生成する実際の機械語が何であるかを理解するのはかなり簡単でした。

全体を周囲の開発環境と一緒に考えると、データ構造のメモリレイアウトと全体的なメモリ配置を完全に制御するのは簡単です。この種のCコードは、C標準で柔軟に実装ベースにできるコンパイラの実装の詳細に依存しているため、全体として移植性がありません。しかし、大規模な場合、Cコード自体はほとんど移植可能です。これは言語の側面であり、Unixなどのシステムで人気を博し、OSの大部分をマシン間で移植できるようにし、実装の実装固有の側面を可能な限り少なくしました。

今日、最新のコンパイラとその最適化により、Cは文字通りではなくなる可能性があります。コンパイラによって実際に最適化が行われるため、Cコードに表示される内容が、アセンブリで取得される内容に文字通り変換されない場合があります。

単純な不自然な例は次のようなものです。

int func(int a, int b) {
    int c;
    int d;

    d = 10;
    return a * d;
}

単純なコンパイラでは、実装はスタックに4つのint、引数に2つ、作業変数に2つを割り当てることができます。明らかな最適化は、「c」変数が使用されていないため、まったく割り当てないことです。さらなる最適化は、「d」も無視し、定数10を使用することです。さらに賢いコンパイラーは、この関数がどのように使用されているかを確認し、呼び出し元の関数に自動的にインライン化して、サブルーチン呼び出しを完全に排除します。

したがって、一方ではコードを見て「これはアセンブリでどのように見えるか」と言うことができるので、アセンブリの上にある低レベルのラッパーとして扱うことができます。一方、最新のコンパイラの最適化を上げてリテラルを少なくすることで、実際の完全な実装ではないにしても、コードで表現しているもののセマンティクスを維持できます。

1
Will Hartung

私が低レベルとは、Cが低レベル言語であると言うときに誰もが意味することです。質問する必要がないことを知っていれば。 –エコウニシス27秒前

それは質問がまったくどのように見えたかではありません。

あなたが知りたいのが彼らが言うときに「低レベル」が何を意味するかであるならば、ウィキはあなたが読みたいかもしれない記事を持っています。

http://en.wikipedia.org/wiki/Low-level_programming_language

http://en.wikipedia.org/wiki/High-level_programming_language

彼らがCが低水準言語であると言うとき、彼らはいかなる程度についても話していません。言語は高レベルまたは低レベルのいずれかです。それらは2つの異なるタイプまたはカテゴリーです。

1
user606723

registerはどうですか?ローカル変数宣言のキーワードで、コンパイラにCPUレジスタに格納するように要求しますが、提案を無視する場合があります。

ただし、GNU Cは、これを拡張して、使用する特定のレジスタを指定できるようにします。

register int foo asm ("a5");
1

Cが覆い隠す主なものは、それが何かを覆い隠す程度まで、いくつかのEdgeの場合のフロー制御です。私がこれまでにアセンブリで記述した、Cにうまく変換されなかったのは、任意のポイントでコードのブロックにホッピングし、その位置から実行し、特定のステータス条件を定期的にチェックし、必要性を見つけたら保存することだけでした。現在のプログラムの場所がどこかにあり、終了しています。次に、次回、コードのブロックが最後に終了したのと同じ位置にジャンプして戻りました。協同組合のコルーチン、私はあなたがそれらを呼ぶと思います。

Cの解決策は、セマフォを介して通信する2つの別々のスレッドを使用することでした。しかし、スレッドはC言語自体の一部ではありません。

1
Tommy