Вы можете отличить статические и локальные переменные, используя их адреса:
Например, вывод следующей программы в моей системе
#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
Предупреждение: я бы не советовал использовать этот «трюк». Вот и все: хитрость, которая сломается в самых неудачных обстоятельствах. Просто документируйте свой макрос правильно и позвольте людям, которые его используют, справиться с последствиями его неправильного использования.