const char * const * nameを登録するもの; この変数が関数の外にあるのはなぜですか?[複製]
void
usage (cpp)
register const char *const *cpp;
{
(void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name);
for (; *cpp; cpp++)
(void) fprintf (stderr, *cpp);
error_exit ();
}
レジスタ変数が中括弧内にない理由がわかりません。fprintfの前にあるこれ(void)は何ですか?また、const char * const * cppを登録します。これまでにこのようなものを見たことがありません。
回答
このregister
キーワードは、その値をプロセッサの専用レジスタに保持することをコンパイラに示すヒントです。これにより、読み取りと書き込みを高速化できます。ただし、最新のコンパイラでは、この種の最適化は不要であるだけでなく、多くの場合逆効果になります。
関数宣言とブロックの間にある理由は、古いc(C90より前)では、パラメーターの横にパラメータータイプを宣言するのではなく、関数の宣言とブロックの間にあるためです。
例えば:
int main(argc, argv)
char ** argv;
{
...
}
argc
型を明示的に定義しない場合、デフォルトでintになるため、何もしなかったことに注意してください。
あなたはこれをあなたが思っているよりも頻繁に見るでしょう。私がFFMPEGで作業したとき、私はこれにたくさん遭遇しました。
(void)キャストは、未使用のパラメーターの警告/エラーを防ぎます。低レベルのコールバック関数を使用してPortAudioで作業しているときに、これに遭遇しました。
「これまでにこれを見たことがない」理由は、これが元の歴史的なK&RCバージョンの構文を使用しているためです。それはあなたが見ているいくつかの本当の古いCコードでなければなりません。調べたところ、1990年にANSI C(C90)がリリースされたので、このコードは少なくとも30年ほど前のものである必要があります。
これは、歴史的なCコードを処理する必要がある場合に知っておく必要があることだと思いますが、そうでない場合は、単に忘れることができます。
(void)
キャストは、それが今日の意味と同じことを意味します。