我有一個只適用於靜態局部變量的宏(因爲它使用內聯彙編符號來提取有關變量的數據)。我需要一種方法來執行,該輸入宏確實是一個靜態的局部變量:如何添加一個靜態斷言來檢查一個變量是否是靜態的?
正確:
func f()
{
static int x;
my_macro(x);
}
不正確:
func f()
{
int x;
my_macro(x);
}
我與海灣合作委員會的工作爲C(無C++)。
我有一個只適用於靜態局部變量的宏(因爲它使用內聯彙編符號來提取有關變量的數據)。我需要一種方法來執行,該輸入宏確實是一個靜態的局部變量:如何添加一個靜態斷言來檢查一個變量是否是靜態的?
正確:
func f()
{
static int x;
my_macro(x);
}
不正確:
func f()
{
int x;
my_macro(x);
}
我與海灣合作委員會的工作爲C(無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發出一個錯誤「初始元素不是常量」非靜態變量。
我認爲你不能在ISO C中區分這些情況。但既然你已經提到你使用GCC,可能會有一些有用的內置僞函數。他們的名字都以__builtin_
開頭,所以你應該閱讀GCC文檔中的列表。
http://www.google.com/search?q=gcc+builtin
好吧,我剛剛經歷了全內置插件部分看完了,我沒有發現任何東西。所以我認爲這是不可能的。
無論如何你只是出於好奇而試圖與宏做什麼?
您可能能夠通過使用他們的地址分辨靜態和局部變量:
靜態變量無論是在.BSS或.DATA段stored
局部變量都存儲在堆棧
例如,在我的系統上輸出以下程序
#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指針strdup()
等,這將導致沒有什麼,但段錯誤沒有一個大問題,不強制的東西。
謝謝!這真的很好。但是,我得到:錯誤:未使用變量'p_searchResp',當我這樣做的時候。你知道如何拒絕嗎? – 2011-04-20 12:45:07
我想通了:你可以在宏中添加memcpy(p_ ## v,&v,sizeof(v)) – 2011-04-21 06:08:07