34

Cでシャドウされたグローバル変数にアクセスするにはどうすればよいですか?C ++では::、グローバル名前空間に使用できます。

4

6 に答える 6

51

file-scope変数が静的でない場合は、ネストされたスコープでexternを使用する宣言を使用できます。

int c;

int main() {
    {
        int c = 0;
        // now, c shadows ::c. just re-declare ::c in a 
        // nested scope:
        {
            extern int c;
            c = 1;
        }
        // outputs 0
        printf("%d\n", c);
    }
    // outputs 1
    printf("%d\n", c);
    return 0;
}

変数がstaticで宣言されている場合、それを参照する方法がわかりません。

于 2009-03-08T08:48:01.590 に答える
5

シャドウされたグローバル変数について話している場合、(Linux では) 次のように使用dlsym()してグローバル変数のアドレスを見つけることができます。

int myvar = 5;    // global

{
    int myvar = 6;    // local var shadows global
    int *pglob_myvar = (int *)dlsym(RTLD_NEXT, "myvar");
    printf("Local: %d, global: %d\n", myvar, *pglob_myvar);
}

コードをセクシーに見せたい場合は、マクロを使用します。

#define GLOBAL_ADDR(a,b)  b =(typeof(b))dlsym(RTLD_NEXT, #a)
...
int *pglob_myvar;
GLOBAL_ADDR(myvar, pglob_myvar);
...
于 2009-03-06T13:42:31.117 に答える
2

C でシールドされたグローバル変数と呼ぶものに応じて、さまざまな答えが可能です。

別のソース ファイルまたはリンクされたライブラリで定義されたグローバル変数を意味する場合は、externプレフィックスを付けて再度宣言するだけで済みます。

extern int aGlobalDefinedElsewhere;

グローバル変数が同じ名前のローカル変数によってシャドウ化されている (または隠されている、好みの用語を選択してください) ことを意味する場合、C でこれを行う組み込みの方法はありません。したがって、それを行わないか、回避する必要があります。それ。考えられる解決策は次のとおりです。

  • グローバル変数にアクセスするための getter/setter 関数 (これは、特にマルチスレッドの状況では良い方法です)

  • ローカル変数の前に定義されたポインターによるグローバルへのエイリアス:

    int noName;
    {
        int * aliasToNoName = &noName; /* reference to global */
        int noName;                    /* declaration of local */
        *aliasToNoName = noName;       /* assign local to global */
    }
    
于 2009-03-06T13:34:23.417 に答える
1

さらに別のオプションは、ローカルを定義する前にグローバルを参照するか、少なくとも最初にグローバルへのポインターを取得して、ローカルを定義した後にアクセスできるようにすることです。

#include <stdio.h>

int x = 1234;
int main()
{
   printf("%d\n",x); // prints global
   int x = 456;
   printf("%d\n",x); // prints local
}
于 2015-08-15T14:35:40.827 に答える