現在、Cは低レベル言語と見なされていますが、70年代に低レベル言語と見なされていましたか?この用語は当時も使用されていましたか?
多くの一般的な高レベル言語は80年代半ば以降まで存在しなかったため、低レベルの性質が長年にわたって変化したかどうか、どのように変化したかを知りたいです。
現在、Cは低レベル言語と見なされていますが、70年代に低レベル言語と見なされていましたか?この用語は当時も使用されていましたか?
多くの一般的な高レベル言語は80年代半ば以降まで存在しなかったため、低レベルの性質が長年にわたって変化したかどうか、どのように変化したかを知りたいです。
回答:
質問の歴史的側面に答えるには:
デザイン哲学は、あなたが聞いたかもしれない「K&R」であるブライアン・カーニガンとCデザイナーのデニス・リッチーによって書かれたCプログラミング言語で説明されています。初版の序文は言う
Cは「非常に高いレベル」の言語でも、「大きな」言語でもありません...
はじめに
Cは比較的「低レベル」な言語です... Cは、文字列、セット、リスト、配列などの複合オブジェクトを直接処理する操作を提供しません。配列全体または文字列全体を操作する操作はありません...
リストはテキストが続く前にしばらく続きます:
これらの機能の一部が存在しないことは重大な欠陥のように思えるかもしれませんが、...言語を控えめなサイズに抑えることには本当の利点があります。
(私は1988年の第2版しかありませんが、以下のコメントは、引用されたテキストが1978年の第1版と同じであることを示しています。)
ですから、はい、当時は「高レベル」と「低レベル」という用語が使用されていましたが、Cはその中間のスペクトルのどこかに位置するように設計されていました。ハードウェアプラットフォーム間で移植可能なCでコードを記述することが可能であり、それが言語が当時高レベルであると見なされたかどうかの主要な基準でした。ただし、Cには高水準言語の特徴であるいくつかの機能が欠けていたため、これは単純さを優先した設計上の決定でした。
これは、高水準言語と低水準言語の定義に依存します。Cが開発されたとき、アセンブリよりも高レベルなものはすべて高レベル言語と見なされていました。これはクリアすべき低いバーです。後に、この用語は、最近ではJavaでさえ低レベル言語であると考える人がいるという点に移行しました。
70年代の高レベルの言語環境内でさえ、Cがかなり低レベルであることを指摘する価値があります。C言語は基本的にBにシンプルな型システムを加えたものであり、Bはアセンブリに便利な手続き型/構造化構文層にすぎません。型システムは型付けされていないB言語の上に後付けされているため、一部の場所でint
は型注釈を省略でき、想定されます。
Cは、その時点で既に確立されていた高価な機能や実装が困難な機能を意識的に除外しています。
Cにはいくつかの興味深い機能があります。
Cが開発された時点で、COBOL、Lisp、ALGOL(さまざまな方言)、PL / I、SNOBOL、Simula、Pascalなどの他の革新的な言語が既に公開されていた、および/または特定の問題領域で広く使用されていました。しかし、これらの既存の言語のほとんどは、メインフレームプログラミング用であるか、学術研究プロジェクトでした。たとえば、ALGOL-60がユニバーサルプログラミング言語として最初に設計されたとき、それを実装するために必要な技術とコンピューターサイエンスはまだ存在していませんでした。これらの一部(一部のALGOL方言、PL / I、Pascal)も低レベルのプログラミングを目的としていましたが、より複雑なコンパイラを使用する傾向があるか、安全すぎる(無制限のポインタがないなど)傾向がありました。Pascalは、可変長配列のサポートが特に不足しています。
これらの言語と比較して、Cは低レベルの開発により実用的であるために、「エレガントな」高価な機能を拒否しています。Cは主に言語設計研究プロジェクトではありませんでした。代わりに、比較的リソースが制約されたPDP-11ミニコンピューターでのUnixカーネル開発の派生物でした。そのニッチ(移植が容易なシングルパスコンパイラでUnixを書くためのミニマリストの低レベル言語)Cは絶対に優れています。45年以上経った今でも、システムプログラミングの共通語です。
%r10
、「静的チェーンポインター」として定義します。これはまさにあなたが話していることです。Cの場合、これは別の呼び出しで上書きされるスクラッチレジスタにすぎませんが、Pascalがそれを使用すると思います。(GNU Cネストされた関数は、あなたがそれに関数ポインタを加えた場合、このような機能は、インライン(例えばので、コンパイラは、スタック上のマシンコードのトランポリンを作成していない場合)は、外側のスコープへのポインタを渡すためにそれを使用します。定期の受容性をr10およびr11の使用法)
a = b;
ISO C89でできるように構造体全体をコピーするのではなく、メンバーを個別にコピーまたはmemcpyする必要があると思います。したがって、初期のCでは、ユーザー定義型は間違いなく第2クラスであり、参照として関数引数としてのみ渡すことができました。 Cの配列に対する嫌悪感と、 C ++が構造体内の配列のメンバーごとの割り当てをサポートするのはなぜですか?
1970年代初頭、Cは最新の構成要素を使用した新鮮な空気のまばゆい息吹でした。UNIXシステム全体をアセンブリ言語からCに書き換えても、スペースやパフォーマンスのペナルティはほとんどありません。当時、多くの同時代人がそれを高級言語と呼んでいました。
Cの著者、主にDennis Ritchieはより慎重であり、Bell System Technical Journalの記事で「Cはそれほど高度な言語ではない」と述べています。デニス・リッチーは、苦笑いして挑発的になるつもりで、低レベルの言語だと言います。Cの設計目標の中で最も重要だったのは、言語をマシンに近づけたまま、移植性、つまりマシンの独立性を提供することでした。
詳細については、元のBSTJの記事を参照してください。
ありがとうデニス。安心してお休みください。
このサイトの他の場所で書いたように、誰かがmalloc / freeメモリ管理パターンを「低レベルプログラミング」と呼んだとき、
「低レベル」の定義が時間とともにどのように変化するか面白い。私が最初にプログラミングを学んでいたとき、単純な割り当て/自由パターンを可能にする標準化されたヒープモデルを提供する言語は、実際に高レベルと見なされていました。では、低レベルのプログラミング、あなたは(!割り当てますが、メモリ位置そのものではない)、メモリの自分を追跡する必要があり、またはあなたが本当に空想感じていた場合は、独自のヒープアロケータを記述します。
コンテキストについては、これはCが出てからかなり後の90年代前半でした。
多くの回答がすでに、「Cは高級言語ではない」などの初期の記事に言及しています。
しかし、私は積み重ねることに抵抗できません:当時、ほとんどまたはすべてではないにしても、多くのまたはすべてのHLL-Algol、Algol-60、PL / 1、Pascal-配列境界チェックと数値オーバーフロー検出を提供しました。
最後にバッファと整数のオーバーフローをチェックしましたが、これが多くのセキュリティ脆弱性の根本原因でした。...はい、それでも...
動的メモリ管理の状況はより複雑でしたが、それでもCスタイルのmalloc / freeはセキュリティの面で大きく後退しました。
したがって、HLLの定義に「多くの低レベルのバグを自動的に防止する」が含まれている場合、CとUNIXが発生していなければ、サイバーセキュリティの残念な状態は非常に異なっているでしょう。
popcnt
。
C(1972)より前の、以前のはるかに高い言語を検討してください。
Fortran-1957(Cよりも高レベルではない)
Lisp-1958
コボル-1959
Fortran IV-1961(Cよりもそれほど高くない)
PL / 1-1964
APL-1966
さらに、RPG(1959)などの中間レベルの言語は、ほとんどがプラグボードベースのユニットレコードシステムに代わるプログラミング言語です。
この観点からすると、Cは非常に低レベルの言語のように見え、当時メインフレームで使用されていたマクロアセンブラの少し上に過ぎません。IBMメインフレームの場合、データベースインターフェースがCobolに移植されていなかったため(当時)、アセンブリとIBMメインフレームで現在も使用されているCobolプログラム。
あなたの質問に対する答えは、質問しているC言語に依存します。
Dennis Ritchieの1974 C Reference Manualで説明されている言語は、高レベル言語のプログラミングの利便性の一部を提供する低レベル言語でした。その言語から派生した方言は、同様に低レベルのプログラミング言語である傾向がありました。
ただし、1989/1990 C Standardが公開されたとき、実際のマシンのプログラミングで一般的になった低レベル言語については説明されていませんでしたが、代わりに-である可能性のある高レベル言語が説明されていました- -低レベルの用語で実装されています。
C Standardの作者が述べているように、この言語を便利にしたことの1つは、多くの実装を高レベルのアセンブラーとして扱うことができるということでした。Cは他の高レベル言語の代替としても使用され、多くのアプリケーションは高レベル言語ではできないことを行う能力を必要としないため、標準の作成者は実装が任意の方法で動作することを許可しましたプログラムが低レベルの構成を使用しようとした場合。したがって、C標準で記述されている言語は、決して低レベルのプログラミング言語ではありません。
この区別を理解するには、リッチーの言語とC89がコードスニペットをどのように表示するかを検討してください。
struct foo { int x,y; float z; } *p;
...
p[3].y+=1;
「char」が8ビット、「int」が16ビットビッグエンディアン、「float」が32ビットで、構造体に特別なパディングまたはアライメント要件がないプラットフォームでは、「struct foo」のサイズは8バイトです。
リッチーの言語では、最後のステートメントの動作は「p」に格納されたアドレスを取得し、それに3 * 8 + 2 [つまり26]バイトを追加し、そのアドレスと次のバイトから16ビット値をフェッチします、その値に1を追加し、その16ビット値を同じ2バイトに書き戻します。動作は、そこに格納されているオブジェクトの種類に関係なく、アドレスpのバイトに続く26バイト目と27バイト目に作用するものとして定義されます。
C標準で定義されている言語では、* pが「struct foo []」の要素を識別し、その後にそのタイプの少なくとも3つの完全な要素が続く場合、最後のステートメントはメンバーyに1を追加します* pの後の3番目の要素。他の状況では、標準によって動作が定義されません。
Ritchieの言語は低レベルのプログラミング言語でした。プログラマーは都合の良いときに配列や構造などの抽象化を使用できる一方で、メモリ内のオブジェクトの基本的なレイアウトに関する動作を定義したためです。対照的に、C89以降の標準で記述されている言語は、高レベルの抽象化に関して用語を定義し、それと一致するコードの動作のみを定義します。低レベルのプログラミングに適した高品質の実装は、標準で義務付けられているよりも多くの場合に有用に動作しますが、そのような目的に適した実装を行う必要があることを指定する「公式」ドキュメントはありません。
したがって、デニスリッチーが発明したC言語は低レベル言語であり、そのように認識されていました。ただし、C規格委員会によって考案された言語は、規格の指令を超える実装提供の保証がないため、決して低レベルの言語ではありませんでした。