『C専門家プログラミング』読書ノート(1)


『C専門家プログラミング』読書ノート(1)
Unixシステム
初期のunixシステムはC言語で書かれたものではなく、unixの出現はC言語より早い.
アセンブリ言語のunixは不器用で、データ構造の作成に多くの時間を浪費し、システムのデバッグが難しく、理解が困難である.
![1554267667790](C:\Users\Alien You\AppData\Roaming\Typora\typora-user-images\1554267667790.png)
Thompson(ベルラボの研究者)は、高度な言語の特徴(アセンブリ言語の欠点を比較)を利用しているが、効率的に実行したくないので、Fortranで短くて成功しない試みを試み、B言語を作成し、言語を研究するためのBCPLを簡略化し、Bの解釈器をPDP-7の8 KBサイズのメモリに常駐させる.ハードウェアシステムのメモリ制限により、コンパイラではなく解釈器の配置のみが許可されるため、B言語によるunix自体のシステムプログラミングが阻害されます.
コンパイラデザイナーの金科玉律:効率(ほとんど)はすべて
コンパイラの効率には、実行効率(コードの実行速度)とコンパイル効率(実行可能なコードを生成する速度)が含まれます.いくつかの開発と学習環境に加えて、実行効率は決定的な役割を果たします.
コンパイルの最適化により、コンパイル時間が長くなりますが、実行時間を短縮できます.
不要なコードの消去やランタイムチェックの無視など、最適化策は、コンパイル時間を短縮し、ランタイムを短縮し、メモリの使用量を削減します.しかし、これらの最適化措置の不利な点は、プログラム内の無効な実行結果が発見される可能性があることであり、最適化措置自体はコードを変換する際に非常に慎重であり、プログラマが不要なコードを記述した場合(例えば、配列境界を越えてオブジェクトを参照し、必要な変数が「知っている」ため)、エラーを引き起こす可能性がある.
コンパイラ・デザイナは、通常、プログラマー一人一人が望む最適化策を選択できるコンパイラ・オプションを提供します.デニスRithieが創造した効率を重視する「New B」は成功し、コンパイラ設計者のこの金科玉律を十分に証明した.
B言語はいくつかの特性(ネストプロセスといくつかの循環構造)を省略することによってBCPL言語を簡略化し,「参照配列要素はポインタにオフセット量を加えた参照に相当する」という考え方を発揚し,BCPL言語(void?)を維持した.タイプがないという特徴は、操作数だけが機械の字です.Thomposonは++と–オペレータを発明し,PDP-7のBコンパイラに加えた.これらはC言語において依然として存在し,PDP−11に対応する自動増減アドレスモデルが存在するためではなく,自動増減機構の出現はPDP−11ハードウェアシステムの出現よりも早い.C言語では
*p++ = *s++

PDP-11コードとして極めて効率的にコンパイルすることができる.
moveb (r0)+, (r1)+

前者は後者に基づいてわざわざ設計されたわけではない.
1970年に開発プラットフォームがPDP-11に移行した後、タイプのない言語はすぐに時宜に合わないように見えた.このプロセッサはハードウェアがいくつかの異なる長さのデータ型をサポートすることを特色としているが、B言語は異なるデータ型を表現することができず、効率も問題であり、ThompsonにPDP-11上でアセンブリ言語を再使用してunixを実現させた.Dennis RitcheはPDP-11の強力な性能を利用して、多くのデータ型と効率を解決する「New B」言語(すぐに「C」になった)を創立し、解釈モードではなくコンパイルモードを採用し、各変数が使用する前に宣言しなければならないタイプシステムを導入した.
C言語の初期体験
追加型システムの主な目的は、コンパイラ設計者が、単一精度浮動小数点数、二重精度浮動小数点数、文字など、新しいPDP-11マシンが持つ異なるデータ型を区別することを支援することである.Pascalのような他の言語とは対照的です.Pascalでは、タイプシステムの目的は、データ上で無効な操作を行わないようにプログラマーを保護することです.設計哲学が異なるため、C言語は強いタイプを排斥し、プログラマーが必要とするときに異なるタイプのオブジェクト間で値を割り当てることができる.タイプシステムは、可用性の面で真剣に評価され、厳格なテストを行ったことがありません.多くのCプログラマーは、「強いタイプ」がキーボードを叩く無駄を増やしたにすぎないと考えている.
最初の数年のC言語の主な取引先はコンパイラの設計者で、多くの特性はコンパイラの設計者のために創立したので、コンパイラの設計者の構想によって発展して形成した言語の特性はあります:
配列の下付き文字は1ではなく0から始まります
これは,オフセット量の概念がコンパイラ設計者の心に根ざしているからである.
C言語の基本データ型は、下位ハードウェアに直接対応
Fortranのように、C言語には内蔵された複数のタイプは存在しません.ある言語要素は、最下位のハードウェアが直接的なサポートを提供していない場合、コンパイラ設計者はその上で精力を浪費することはありません.C言語は最初は浮動小数点タイプをサポートしていませんでしたが、ハードウェアシステムが浮動小数点数を直接サポートできるまでサポートしていません.
autoキーワードは明らかに飾りです
このキーワードは、シンボルテーブルエントリを作成するコンパイラ設計者にのみ意味があります.これは、「ブロックに入ると自動的にメモリ割り当てが行われる」(グローバル静的割り当てまたはスタック上の動的割り当てとは逆)という意味です.他のプログラマーはautoというキーワードを心配する必要はありません.デフォルトの変数メモリ割り当てモードです(デフォルト).
式の配列名は、時ポインタと見なすことができます.
配列をポインタと見なし、1つの関数に渡すときにすべての配列の内容をコピーしなければならない非効率に耐える必要はありません.しかし,配列とポインタはいずれの場合も等価ではない(本第4章)
floatはdoubleに自動的に拡張されます
ANSI Cではそうではありません.初期のunixプログラムでは、floatがdoubleに変換されるコストは非常に小さく、後にビットごとに0の字を1つ増やせばよいが、変換するには2番目の字を削除すればよい.また、いくつかのPDP-11の浮動小数点ハードウェア表現形式には、floatの演算のみを行うこともdoubleの演算のみを行うこともできる(すなわち、この2つの方式の演算を行うには演算モードビットを変更する必要がある)演算モードビットがあり、この初期には演算モードをdoubleに固定するのが便利であるため、コンパイラ設計者がその変化を追跡するのを省くことができます.
ネストされた関数は許可されていません(関数の内部に別の関数の定義が含まれています)
コンパイラを簡略化し、Cプログラムの実行時組織構造を少し向上させる.
registerキーワード
コンパイラ設計者に手がかりを提供することができます.プログラム内のどの変数がよく使われているのか、レジスタに格納することができます.この設計は誤りと言えるが,コンパイラが各変数を使用する際にレジスタの割り当て作業を自動的に処理させるのは,宣言されると,このような変数をライフタイム内に常にレジスタに残すよりもよい.これはコンパイラを簡略化したが,プログラマーに風呂敷を捨てた.
Unixシステムの広範な使用は、C言語をすくすくと成長させた.C言語はハードウェアによって直接サポートされる最下位の操作を強調し、極めて高い効率と移植性をもたらし、逆にunixの大きな成功を助けた.