11

Cでは、ポインタを使用すると、関連付けられた変数の「レジスタ」プロパティがキャンセルされますか?

#include<stdio.h>
#include<stdlib.h>
int main()
{
    register int clk=0;    //maybe register maybe not
    int *adr=&clk;         //not a register now? i have its address
    *adr=1;  //if i use this 1000000 times, does it exist in L1 at least?
    printf("%d",clk);
    return 0;

}

「レジスタ変数のアドレスを取得できません」というコンパイラ エラーが発生しますが、レジスタ %100 ではありません。それはただのチャンスです。

これは最も遅いループですか?

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p;
    int i=0;
    p=&i;
for(*p=0;(*p)<100;(*p)++)
{
    //do nothing
}
    printf("%d ",i);
    return 0;

}

ほぼすべての変数をポインター スタイルにし、3 つの変数のみを "register" キーワードでプリミティブ型にすると、コンパイラはこれら 3 つの変数をより高い確率で "実際に登録" しますか?

わかった。問題が解決しました。私はいくつかのアセンブリを学び、これが最適化レベルと変数のボラティリティにも依存することを発見しました。__asm{} を使用すると、確実にレジスターで計算されます。ありがとう。

4

2 に答える 2

27

C では、指定子&で宣言された変数に適用することは違法です。register

6.7.1

実装では、任意のレジスタ宣言を単純に auto 宣言として扱うことができます。ただし、アドレス可能なストレージが実際に使用されているかどうかにかかわらず、ストレージ クラス指定子 register で宣言されたオブジェクトのどの部分のアドレスも、明示的に ( 6.5.3.2 で説明したように単項 & 演算子を使用して) 計算することも、暗黙的に (6.5.3.2 で説明したように)計算することもできません。 6.3.2.1 で説明されているように、配列名をポインターに変換することによって)。

そして 6.5.3.2:

単項 & 演算子のオペランドは、関数指定子、[] または単項 * 演算子の結果、またはビットフィールドではなく、register ストレージ クラス指定子で宣言されていないオブジェクトを指定する左辺値のいずれかでなければなりません。 .

C++ に関しては、 & を とともに使用すると、registerその意味が取り消されます。

ANSI C では、レジスタ オブジェクトのアドレスを取得できません。この制限は C++ には適用されません。ただし、アドレス演算子 (&) がオブジェクトで使用されている場合、コンパイラはアドレスを表すことができる場所にオブジェクトを配置する必要があります。実際には、これはレジスタではなくメモリ内を意味します。

于 2012-07-09T10:33:53.157 に答える
1

&をレジスタ変数に使用すると、この変数がメインメモリになり、アドレスを取得できるようになります。レジスタ変数にアドレスがないためです。

于 2012-07-09T10:38:37.260 に答える