3

ストレージクラスをレジスタとして宣言すると、その可用性に応じてレジスタに格納されるという本を読みました。使用可能なレジスターがない場合は、デフォルトのストレージ タイプ 'auto' が割り当てられます。

ストレージ クラスを明示的に指定せずに変数を宣言すると、変数に割り当てられるデフォルトのストレージ タイプは「auto」自体になります。

したがって、私の質問は、すべての変数を「レジスタ」ストレージ クラスであると宣言しない理由です。使用可能なレジスタがない場合は、とにかくデフォルトの「自動」クラス自体として扱われます。幸いなことに、レジスターが使用可能であれば、1 つのレジスターに保管されます。& 演算子を使用できなくなったことは理解していますが、ポインターとアドレスを使用しない場合はどうすればよいでしょうか? これらの変数を 'register' ストレージ クラスで宣言できますか? これは悪い習慣のように思われるからです。

編集:ウェブを検索しましたが、「アドレスが利用できない」という点だけが言及されています。「レジスタ」で残りの変数を宣言できない理由については言及されていません。

4

2 に答える 2

6

registerC (および (C++) 言語仕様では、変数のアドレスの取得が明示的に禁止されているため、すべての変数を作成することはできませんregister

ただし、修飾子registerは、 GCCClang/LLVMなどの今日の最適化コンパイラでは何の役割も果たしておらず、これらのコンパイラは、修飾されていない変数に対して喜んで自由にマシン レジスタを使用するか、修飾された変数を (マシン レジスタではなく) メモリに保持します。. 基本的に、コンパイラは修飾子を無視します(そのアドレスの取得を禁止する場合を除く)。複雑なレジスタ割り当てアルゴリズムとヒューリスティックがあります。特定の変数は、関数コードの一部の部分ではマシン レジスタに残り、他の部分ではメモリに格納される場合があります。registerregisterregister

最適化の観点から見ると、現在のコンパイラは、同じ方法で変数を処理autoし、register修飾します (したがって、register修飾子は、address-of 演算子を禁止する以外は役に立ちません)。

また、現在、 CPU キャッシュはプロセッサ レジスタよりもはるかに重要であることに注意してください。パフォーマンスのために C コードを手動で調整したい場合 (コンパイラーは自分よりも優れているため、これはしばしば悪い考えです)、キャッシュの問題に注意することをお勧めします (これを参照してください)。

私の知る限り、C および C++ 言語の将来のバージョンでは、register(修飾子の場合autoと同様に) 修飾子が正式に非推奨になり、将来の言語仕様でそのキーワードが他の目的で再利用される可能性があります (C++11 が再利用したようにauto)。したがって、ソース コードでを使用registerするのはおそらく間違いです。コードを C または C++ の将来のバージョンに移植するのが難しくなる可能性があるからです。

于 2015-06-14T04:59:34.300 に答える
3

「register」キーワードは、可能であれば変数を他のものよりも速く処理する必要があると考えるコンパイラへのヒントにすぎません。副作用として、変数のアドレスを取得することは許可されておらず、レジスタ配列は未定義の動作です。

最近のコンパイラはとにかく可能な限りレジスタを使用するため、このキーワードはもう必要ありません。コンパイラは、あなたよりも賢く、プログラムのある部分で変数 x のレジスタを使用し、プログラムの別の部分で変数 y のレジスタを使用できます。または、構造体の 5 つのフィールドのうち 2 つにレジスタを使用します。register キーワードでは表現できないすべてのこと。

register の使用が完全に無意味ではない唯一のケースは、他の変数よりもはるかに使用されていないように見える変数がある場合ですが、よく知っています。それでも、それは非常に大きな「5月」です。

于 2015-06-14T05:25:19.133 に答える