プログラミング言語C – 宣言 – 記憶クラス指定子
津路です。
引き続き、プログラミング言語C 第2版 ANSI規格準拠 K&R著(共立出版)を読んで、気になるところを書いています。
今回は、A8 宣言を取り上げます。
宣言の概要から、「各識別子に与えられる解釈を指定するのに使われる。それらには必ずしも識別子に付随したメモリが確保されるわけではない。メモリを確保する宣言は定義と呼ばれる。」
メモリが確保されるわけではない、というのが重要です。
「宣言の形式は
declaration:
declaration-specifiers init-declarator-list ;
である。init-declarator-list の中の宣言子は宣言されるべき識別子を含む。宣言指定子は、型と記憶クラスの指定子の列からなる。」
以下の各形式は、ここでは省略します。
続いて、「宣言子については後で述べる。これには宣言される名前が含まれる。一般に宣言は少なくとも1つの宣言子をもたねばならない。あるいはその型指定子は構造体のタグ、共用体のタグ、あるいは列挙のメンバーを宣言するものでなければならない。空の宣言は許されない。」
上記のタグとは、構造体指定子、共用体指定子、列挙指定子が指定する内容を示す識別子のことです。
このあと、各指定子について説明があります。
A8.1 記憶クラス指定子
auto, register, static, extern, typedef
以上のうち、一つの宣言ではどれか一つしか指定できません。
「auto と registerの指定子は、宣言されたオブジェクトに対し自動記憶クラスを与えるもので、関数の中でのみ使える。」
「そうした宣言はまた定義としても意味をもち、これによりメモリが割り当てられる。
register 宣言は、一種のauto宣言で、かつその変数の使用頻度が多いことを知らせるものである。これでレジスタに実際に格納されるオブジェクトは数個しかなく、しかも許されるのはある型の変数のみである。この制限は処理系に左右される。
しかしながら、あるオブジェクトがregisterと宣言されると、単項の & 演算子は、明示的にも暗黙的にもそれには適用できなくなる。」
register と宣言してしまうと、それがレジスタに保存される限り、アドレスが取れない、と書いてあります。ANSI C言語辞典には、アドレスがないと書いてあります。
実際に register と宣言しても、その数は非常に少なく、autoと扱われるかもしれないので、あらかじめその数を知りたいところです。
ところが、対象の処理系によほど詳しいプログラマ、つまり組み込み系などでないと、効果は期待できないのが現実です。
つまり、プログラマの裁量によって、有効になったり、無効になったりします。
VC++では無視され、gccでは、理解して指定する限りは有効になるようです。
といっても、コンパイラは最適化をするわけですから、無視するからといって悪いわけではありません。
registerは、C++11で非推奨化されたようです。
続きは、次回に。。