2014-11-12

最近のC言語の配列

N4188を読んでいて、C言語の規格を参照する必要が出てきたので、C言語の規格を読んだのだが、最近のC言語の配列は、面白いことになっている。

以下はすべて最新のC規格で合法なコードである。

void f( char a[ * ] ) ;
void g( char a[ static 100 ] ) ;
void h( char a[ const volatile restrict ] ) ;
void wtf( char a[ static const volatile restrict 1 ] ) ;

これは、関数のプロトタイプ宣言でのみ許されている。

[*]は、サイズを指定しない可変長配列型である。関数のプロトタイプ宣言スコープの中でしか使えない。[]との違いは、完全形であることだ。

[static n]は、関数を呼び出した際の実引数は、少なくともn個の要素を持たなければならない。

void f( char a[ static 10 ] ) ;

int main()
{
    char a[10] ;
    f( a ) ; // OK

    char b[9] ;
    f( b ) ; // ill-formed
}

コンパイラーはこの情報を最適化のヒントなどに使える。

[ type-qualifier-list ] は、よくわからない。この意味を定義する文面が見つからない。一体なんだろうか。

ドワンゴ広告

この記事はドワンゴ勤務中に書かれた。

ドワンゴにはボルダリング部がある。今夜は仕事帰りにボルダリングをしようと思う。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

3 comments:

y121516 said...

関数の引数型に配列型を指定した場合、ポインタに型調整されますが、その時にtype-qualifier-listが考慮されます。

規格にも例が載っていますが
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
は同じです。

江添亮 said...

やはりそういう意味だったか。
まあ、ポインターよりは書きやすいか。

Anonymous said...

C言語にこそテンプレートが入ってほしいです。mallocのカオスったらひどいもんです。メタプロはやらないのでできなくてもいいです。そのうえでJS化してほしいです。さっさとバリアント変数を策定するよろし!