web-dev-qa-db-ja.com

それが出たとき、Cプログラミング言語は低レベル言語と考えられていましたか?

現在 [〜#〜] c [〜#〜]低レベル言語 と見なされていますが、70年代に戻って低レベルと見なされましたか?その用語は当時も使用されていましたか?

80年代半ば以降まで、人気の高い高水準言語の多くは存在していなかったので、低水準の性質が長年にわたって変化したかどうか、またどのように変化したかについて知りたいです。

152
joeyfb

質問の歴史的側面に答えるには:

設計哲学は、Brian KernighanとCデザイナーであるDennis Ritchieが書いたCプログラミング言語で説明されています。初版の序文によると

Cは「非常に高水準」な言語でも、「大きな」言語でもありません...

はじめに

Cは比較的「低レベル」の言語です... Cは、文字列、セット、リスト、配列などの複合オブジェクトを直接処理する操作を提供しません。配列全体または文字列を操作する操作はありません...

リストはテキストが続く前にしばらく続きます:

これらの機能のいくつかがないことは重大な欠陥のように見えるかもしれませんが...言語を適度なサイズに抑えることには本当の利点があります。

(1988年の第2版しかありませんが、以下のコメントは、引用されたテキストが1978年の第1版でも同じであることを示しています。)

はい、そうです、「高レベル」と「低レベル」という用語はその当時使用されていましたしかし、Cはその中間のスペクトルのどこかに入るように設計されました。ハードウェアプラットフォーム間で移植可能なCでコードを書くことが可能であり、それが言語が当時高水準であると見なされたかどうかの主な基準でした。ただし、Cには高水準言語に特徴的ないくつかの機能が欠けていたため、これは単純さを優先する設計上の決定でした。

142
gatkin

これは、高水準言語と低水準言語の定義によって異なります。 Cが開発されたとき、Assemblyよりも高水準のものはすべて高水準言語と見なされていました。それはクリアするための低いバーです。その後、この用語は、一部の人が最近Javaでさえ低レベル言語であると見なすようになると思われるようになりました。

70年代の高水準の言語環境の中でさえ、Cはかなり低いレベルであることを指摘する価値があります。 C言語は基本的にBに単純な型システムを加えたものであり、Bはアセンブリ用の便利な手続き型/構造化構文レイヤーにすぎません。型システムは型なしB言語の上にレトロフィットされているため、一部の場所では型注釈を省略でき、intが想定されます。

Cは、次のような当時すでに確立されていた機能を実装するのに費用がかかるか困難であることを意識的に除外しています。

  • 自動メモリ管理
  • ネストされた関数またはクロージャー
  • 基本OOPまたはコルーチン
  • より表現力豊かな型システム(例:範囲制限型、レコード型などのユーザー定義型、厳密な型指定など)

Cには興味深い機能がいくつかあります。

  • 再帰のサポート(スタックベースの自動変数の結果として、すべての変数がグローバルライフタイムを持つ言語と比較して)
  • 関数ポインタ
  • ユーザー定義のデータ型(構造体と共用体)は、Cの最初のリリース直後に実装されました。
  • Cの文字列表現(pointer-to-chars)は、実際には、複数の文字を1つのマシンワードにエンコードするBよりも大幅に改善されています。
  • 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年以上経った今でも、システムプログラミングのlingua francaです。

157
amon

1970年代初頭、Cは近代的な構成を使用して新鮮な空気のまばゆい息吹でしたので、UNIXシステム全体をアセンブリ言語からCに書き直すことができ、スペースやパフォーマンスのペナルティはほとんどありませんでした。当時、多くの同時代人はそれを高級言語と呼んでいました。

Cの作者、主にDennis Ritchieはより慎重で、Bell System Technical Journalの記事で「Cはそれほど高級な言語ではない」と述べています。デニス・リッチーは苦笑いし、挑発するつもりで、それは低レベルの言語だと言います。彼のCの設計目標の中で主なものは、言語をマシンに近づけながら、移植性、つまりマシンに依存しないことを提供することでした。

詳細については、 元のBSTJ記事: を参照してください

デニスありがとう。安心してお休みいただけますか。

37
bud wonsiewicz

私が書いたように このサイトの他の場所 誰かがmalloc/freeメモリ管理パターンを「低レベルのプログラミング」と呼んだとき、

「低レベル」の定義が時間とともにどのように変化するかおかしい。私が最初にプログラミングを学んでいたとき、単純な割り当て/解放パターンを可能にする標準化されたヒープモデルを提供する言語は、実際には高レベルと見なされていました。 低レベルプログラミングでは、メモリを自分で追跡する必要があります(割り当てではなく、メモリの場所自体を追跡する必要があります!)、または本当に気が利いているなら、独自のヒープアロケータを書いてください。

コンテキストとしては、これはCがリリースされてからかなり後の90年代のことです。

21
Mason Wheeler

多くの回答は、「Cは高水準言語ではない」などのことを述べた初期の記事をすでに参照しています。

ただし、積み重なることに抵抗することはできません。当時、ほとんどまたはすべてではないにせよ、多くのHLL(ALGOL、ALGOL-60、PL/1、Pascal)は、配列境界チェックと数値オーバーフロー検出を提供していました。

最後に、バッファと整数オーバーフローが多くのセキュリティの脆弱性の根本的な原因であることを確認しました。 ...うん、まだそうだ...

動的メモリ管理の状況はより複雑でしたが、それでも、Cスタイルのmalloc/freeはセキュリティの点で大きな後退でした。

したがって、HLLの定義に「多くの低レベルのバグを自動的に防止する」が含まれている場合でも、CとUNIXが発生していなかった場合、サイバーセキュリティの残念な状態は非常に異なり、おそらくより良いでしょう。

15
Krazy Glew

C(1972)より前の、より古くより高度な言語を考えてみましょう。

Fortran-1957(Cよりはるかに高いレベル)

LISP-1958

コボル-1959

Fortran IV-1961(Cよりはるかに高いレベルではない)

PL/1-1964

APL-1966

さらに、RPG(1959)のような中級言語、主にプラグボードベースのユニットレコードシステムを置き換えるプログラミング言語。

この観点から見ると、Cは非常に低レベルの言語のように見え、当時メインフレームで使用されていたマクロアセンブラより少しだけ上にありました。 IBMメインフレームの場合、データベースインターフェースがCobolに移植されていなかったため(当時)、BDAM(ベーシックディスクアクセス方式)などのデータベースアクセスにアセンブラマクロが使用され、その結果、アセンブリとCobolプログラムは、現在IBMメインフレームで現在も使用されています。

8
rcgldr

あなたの質問への答えは、それが尋ねているC言語に依存します。

Dennis Ritchieの1974 Cリファレンスマニュアルで説明されている言語は低水準言語であり、高水準言語のプログラミングの利便性の一部を提供していました。その言語から派生した方言も同様に低レベルのプログラミング言語である傾向がありました。

ただし、1989/1990 C標準が公開されたとき、実際のマシンのプログラミングで一般的になった低水準言語については説明されていませんが、代わりに、可能性のある高水準言語について説明していました。 -下位レベルで実装されます。

C Standard Noteの作成者として、この言語を有用にした理由の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つの完全な要素が続く場合、最後のステートメントは1をメンバーyに追加します。 * pの後の3番目の要素。その他の状況下では、行動は規格によって定義されません。

Ritchieの言語は低レベルのプログラミング言語でした。なぜなら、プログラマは配列や構造などの抽象化を都合のよいときに使用できる一方で、メモリ内のオブジェクトの基本的なレイアウトの観点から動作を定義したからです。対照的に、C89以降の標準で記述されている言語は、より高いレベルの抽象化の観点から物事を定義し、それと一致するコードの動作のみを定義します。低レベルのプログラミングに適した高品質の実装は、標準で義務付けられているよりも多くの場合に有効に動作しますが、そのような目的に適するように実装が何をしなければならないかを指定する「公式」文書はありません。

したがって、デニス・リッチーによって発明されたC言語は低水準言語であり、そのように認識されました。ただし、C標準委員会によって発明された言語は、標準の義務を超える実装提供の保証がない限り、決して低レベルの言語ではありませんでした。

6
supercat