好的,原来我之前的回答不适用于静态全局变量,所以我设计了这个程序,可以检查全局变量是否声明为静态。它的工作方式是dysym() 在符号表中找不到静态全局变量,所以我只检查它的输出。它还使用布尔值引用变量,并确保它确实存在。
#include <stdio.h>
#include <dlfcn.h>
char* a = "hello, world";
static char* b = "hello, world";
#define is_static(name) \
(is_sym_static(#name) && &name)
_Bool is_sym_static(const char* const name)
{
void* hdl = dlopen(NULL, 0); // TODO: optimise by only calling this once.
return dlsym(hdl, name) == NULL;
}
int main(int argc, char** argv)
{
printf("%i\n", is_static(a)); // prints 0
printf("%i\n", is_static(b)); // prints 1
}
这必须用-ldl -Wl,--export-dynamic 编译,以确保所有变量最终都在符号表中。这不适用于局部变量,但我们可以将它与我之前的答案结合起来......
#include <stdio.h>
#include <dlfcn.h>
#include <sys/resource.h>
static char* stack_start;
#define is_static(name) \
(is_addr_static(&name) && is_sym_static(#name) && &name)
_Bool is_sym_static(const char* const name)
{
void* hdl = dlopen(NULL, 0); // TODO: optimise by only calling this once.
return dlsym(hdl, name) == NULL;
}
_Bool is_addr_static(void* var)
{
struct rlimit stack;
getrlimit(RLIMIT_STACK, &stack); // TODO: optimise by only calling this once.
char* stack_end = stack_start - stack.rlim_cur;
return !((char*)var < stack_start && (char*)var > stack_end);
}
char* a = "hello, world";
static char* b = "hello, world";
int main(int argc, char** argv)
{
char _;
stack_start = &_;
char* c = "hello, world";
static char* d = "hello, world";
printf("%i\n", is_static(a)); // prints 0
printf("%i\n", is_static(b)); // prints 1
printf("%i\n", is_static(c)); // prints 0
printf("%i\n", is_static(d)); // prints 1
}
现在可以检测全局和局部静态变量。但是,我认为没有理由需要这个,因为本地静态和全局静态是根本不同的东西。