3

静的ローカル変数でのみ適切に機能するマクロがあります (インライン アセンブリ表記を使用して変数に関するデータを抽出するため)。マクロへの入力が実際に静的ローカル変数であることを強制する方法が必要です。

正しい:

func f()
{
    static int x;
    my_macro(x);
}

正しくありません:

func f()
{
    int x;
    my_macro(x);
}

C用のGCC(C++なし)を使用しています。

4

4 に答える 4

4

次のトリックを使用できます。

#define ASSERT_LOCAL_STATIC(v) static void *p_ ## v = &v

void fn()
{
    int nonstatic_var = 0;
    static int static_var = 0;

    ASSERT_LOCAL_STATIC(static_var);
    ASSERT_LOCAL_STATIC(nonstatic_var);
}

GCC は、非静的変数に対して「初期化要素が定数ではありません」というエラーを発行します。

于 2011-04-15T05:13:10.723 に答える
3

アドレスを使用して、静的変数とローカル変数を区別できる場合があります。

  • 静的変数は、.BSS または .DATA セクションに格納されます。

  • ローカル変数はスタックに格納されます

たとえば、私のシステムでの次のプログラムの出力

#include <stdio.h>

void f0() {
    int x = 0;
    printf("%p\n", &x);
}

void f1() {
    static int x = 0;
    printf("%p\n", &x);
}

int main() {
        f0();
        f1();

        return 0;
}

これは:

0x7fff1dc718dc
0x600900

各セクションとスタックが配置される場所は、プラットフォームの ABI によって異なりますが、ブロック ローカル変数のアドレスを使用して条件を形成できます。

#include <stdio.h>

#define check(var) { \
        int ___ = 0; \
        printf("%s (%p): %s\n", #var, &var, (&var > &___)?"local":"static"); \
}

void f0() {
    int x = 0;
    check(x);
}

void f1() {
    static int y = 0;
    check(y);
}

int main() {
        f0();
        f1();

        return 0;
}

これは以下を出力します:

x (0x7fff4b965afc): local
y (0x600978): static

警告: この「トリック」の使用はお勧めしません。それがすべてです:トリック、最も不都合な状況で壊れるトリック。マクロを適切に文書化し、それを使用する人にその誤用の結果を処理させてください。

于 2011-04-13T07:30:47.257 に答える
2

ほとんどの C ライブラリが使用する方法で単純に実行します。マクロは静的変数に対して機能し、それ以外の動作は未定義/予期しない可能性があることをユーザーに伝えます。

NULL ポインタを etc. に渡すこともできるのと同じようにstrdup()、セグメンテーション違反だけが発生します。強制しないことには大きな問題はありません。

于 2011-04-13T07:33:24.473 に答える
0

ISO Cではこれらのケースを区別できないと思います。しかし、GCCを使用することはすでに述べたので、いくつかの便利な組み込みの疑似関数があるかもしれません。それらの名前はすべて、で始まる__builtin_ため、GCCドキュメントのそのリストを読む必要があります。

http://www.google.com/search?q=gcc+builtin

組み込みのセクション全体を読んだだけで、何も見つかりませんでした。ですから、それは本当に不可能だと思います。

好奇心から、とにかくマクロで何をしようとしていますか?

于 2011-04-13T07:23:37.330 に答える