静的ローカル変数でのみ適切に機能するマクロがあります (インライン アセンブリ表記を使用して変数に関するデータを抽出するため)。マクロへの入力が実際に静的ローカル変数であることを強制する方法が必要です。
正しい:
func f()
{
static int x;
my_macro(x);
}
正しくありません:
func f()
{
int x;
my_macro(x);
}
C用のGCC(C++なし)を使用しています。
静的ローカル変数でのみ適切に機能するマクロがあります (インライン アセンブリ表記を使用して変数に関するデータを抽出するため)。マクロへの入力が実際に静的ローカル変数であることを強制する方法が必要です。
正しい:
func f()
{
static int x;
my_macro(x);
}
正しくありません:
func f()
{
int x;
my_macro(x);
}
C用のGCC(C++なし)を使用しています。
次のトリックを使用できます。
#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 は、非静的変数に対して「初期化要素が定数ではありません」というエラーを発行します。
アドレスを使用して、静的変数とローカル変数を区別できる場合があります。
静的変数は、.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
警告: この「トリック」の使用はお勧めしません。それがすべてです:トリック、最も不都合な状況で壊れるトリック。マクロを適切に文書化し、それを使用する人にその誤用の結果を処理させてください。
ほとんどの C ライブラリが使用する方法で単純に実行します。マクロは静的変数に対して機能し、それ以外の動作は未定義/予期しない可能性があることをユーザーに伝えます。
NULL ポインタを etc. に渡すこともできるのと同じようにstrdup()
、セグメンテーション違反だけが発生します。強制しないことには大きな問題はありません。
ISO Cではこれらのケースを区別できないと思います。しかし、GCCを使用することはすでに述べたので、いくつかの便利な組み込みの疑似関数があるかもしれません。それらの名前はすべて、で始まる__builtin_
ため、GCCドキュメントのそのリストを読む必要があります。
http://www.google.com/search?q=gcc+builtin
組み込みのセクション全体を読んだだけで、何も見つかりませんでした。ですから、それは本当に不可能だと思います。
好奇心から、とにかくマクロで何をしようとしていますか?