プログラミング言語C-定数式
津路です。
引き続き、プログラミング言語C 第2版 ANSI規格準拠 K&R著(共立出版)を読んで、気になるところを書いています。
今回は、A7.19 定数式を取り上げます。
最初の主題は、「構文的には、定数式は演算子のサブセットにのみ限られた式である。」という文語です。
「constant-expression:
conditional-expression」
「定数に評価される式が要求される文脈は次のようにいくつかある。caseの後、配列の境界およびビット・フィールドの長さとして、列挙定数の値として、初期値式の中、ある種のプリプロセッサの中。」また、文語調です。
以下のような式では、定数と評価されます。case文、配列の添え字、ビット・フィールドのビット数指定子、列挙定数の値、プリプロセッサの一部など。
次の文章「sizeofの被演算数の中を除き、定数式の中には、代入、インクリメントおよびデクリメントの演算子、関数呼び出し、コンマ演算子を含めてはならない。」
sizeofは、関数ではありません、演算子です。使い方は2通りあります。
1 2 3 | char c; printf("size of c %zu\n",sizeof c); //単項式 printf("size of c %zu\n",sizeof(char)); //型名 |
単項式は、評価されません。そのため、sizeofの被演算子では、代入などの演算子を、例外として使用できます。が、評価されないのですから、そもそも使用しないことです。
定数式には、代入演算子、++/–、関数呼び出し、コンマ演算子を使用できません。
「定数式が整数のものであることが要求されるときには、その被演算数は整数、列挙、文字、浮動小数でなければならず、型変換では整数型を指定し、任意の浮動小数は整数に型変換しなければならない。」
定義する定数式を整数型と認識させるには、被演算数は、整数、文字、浮動小数のうちいずれかの定数で構成します。
「これで配列、間接参照、アドレス演算、構造体のメンバー操作は当然排除される。」
ここで主張されているのは、以上の制限により、間接参照やアドレス演算、構造体のメンバー操作を抑止できるメリットです。
文章は、初期化式に移行します。
「一方、初期化のための定数式にはもっと自由度が許される。被演算数は任意の型の定数でよく、単項の&演算子は、外部のあるいは静的なオブジェクト、あるいは定数式で添え字をつけた外部あるいは静的な配列に適用しても良い。」
「単項の&演算子はまた添え字なしの配列や関数を使うことによって暗黙のうちに適用することもできる。」
例をあげると、
char arr[2]={‘a’,’b’};
char *arr2 = arr;
などでしょうか?
「さらに初期値式は、それを評価したとき、定数か、あるいは前に宣言された外部のあるいは静的なオブジェクトに定数を足したもの、あるいは引いたものになっていなければならない。」
この文章は、後半の係り受けがおかしいです。「アドレス」が抜けています。
正しくは、「。。。あるいは、前に宣言された外部か静的なオブジェクトのアドレスに、定数をプラス・マイナスした。。。」ですね。