「char s [static 10]」のような関数の配列パラメーターの静的キーワードの目的は何ですか?


144

いくつかのソースコードを閲覧しているときに、次のような関数を見つけました。

void someFunction(char someArray[static 100])
{
    // do something cool here
}

いくつかの実験で、他の修飾子もそこに現れるかもしれません:

void someFunction(char someArray[const])
{
    // do something cool here
}

修飾子は[ ]、配列が関数のパラメーターとして宣言されている場合にのみ許可されているようです。これらは何をしますか?関数パラメーターの場合はなぜ違うのですか?

回答:


127

最初の宣言は、コンパイラ指示someArrayである少なくとも 100個の要素長期。これは最適化に使用できます。たとえば、それsomeArrayは決してないことも意味しNULLます。

C標準では、関数の呼び出しがこれらの要件を満たさない場合(つまり、定義されていない動作がサイレントである場合)にコンパイラが診断する必要がないことに注意してください。

2番目の宣言は単にsomeArraysomeArray要素ではなく!)constとして宣言しますsomeArray=someOtherArray。つまり、書き込むことはできません。パラメータがの場合と同じchar * const someArrayです。

この構文は[]、関数パラメーターリストの配列宣言子の最も内側でのみ使用できます。他の状況では意味がありません。

上記の両方のケースをカバーする標準テキストは、C11 6.7.6.3/7にあります(C99では6.7.5.3/7でした):

「」型の配列「としてパラメータの宣言」「」を入力する修飾ポインタ「」に調整されなければならない、タイプ修飾子は、(もしあれば)内に指定されたものである[]アレイ型導出。キーワードstaticが[]の配列型の派生にも含まれている場合、関数の呼び出しごとに、対応する実際の引数の値が、少なくともで指定された数の要素を持つ配列の最初の要素へのアクセスを提供しますサイズ式。


35
このトピックについて:NULLポインターを受け入れない関数のシグニチャーとしてではint foo(struct bar [static 1]);なく、を使用することをおint foo(struct bar *);勧めしますか?(gccには、コンパイラーが警告を出すことができるように、そのような関数にフラグを立てる代替の非標準構文があることを知っています。)
R .. GitHub STOP HELPING ICE

2
私はgccとclangをチェックしたばかりで、0と比較するように要求したときにsomeArrayが常にnullでないとは想定していません。また、それを定義するC99の正確な句を見つけるのに苦労しています。6.7.5.3-21には、意図された意味についての注記があり、それだけです。これが信頼できるとは思えません。さらに、これはすべて関数シグネチャの一部ではないため、それを介して実行することはあまりありません。
Nordic Mainframe

5
そのリンクは腐敗しているように見えますが、これはそれが指しているものですか?pic.dhe.ibm.com/infocenter/zos/v1r12/…–
ロスエイケン

13
@NordicMainframe:しばらく時間が経過しましたが、現在のバージョンの現在のバージョンでclangは、[static 1]パラメータ宣言を使用して既知のNULL引数を関数に渡そうとすると、正しく警告が表示されます。
dreamlax 14

1
@CiroSantilli巴撤馬文件六四事件法轮機能if (!someArray) { somecode... }を削除できました
MM
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.