2011-04-13 5 views
3

정적 로컬 변수에서만 잘 작동하는 매크로가 있습니다 (인라인 어셈블리 표기법을 사용하여 변수에 대한 데이터를 추출하기 때문에). 없음 (나는 C에 대한 GCC와 함께 작동변수가 정적인지 확인하기 위해 정적 어설 션을 추가하려면 어떻게합니까?

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

:

올바른 : 정확하지

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

나는 매크로 입력이 참으로 정적 지역 변수를 적용하는 방법이 필요 C++).

답변

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는 오류 비 정적 변수의 "초기화 요소가 일정하지"발행합니다.

+0

감사! 이것은 정말로 멋지다. 그러나, 나는이 트릭을 할 때 error : unused 변수 'p_searchResp'를 얻는다. 이것을 피하는 법을 아십니까? –

+0

나는 이것을 알아 냈다 : 매크로에 memcpy (p_ ## v, & v, sizeof (v))를 추가 할 수있다. –

0

ISO C에서 이러한 경우를 구별 할 수 없다고 생각합니다. 그러나 이미 GCC를 사용한다고 언급 했으므로 유용한 내장 내장 의사 함수가있을 수 있습니다. 그들의 이름은 모두 __builtin_으로 시작하기 때문에 GCC 문서의 해당 목록을 읽어야합니다.

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

음은, 난 그냥 전체 내장 기능 섹션을 통해 읽고, 난 아무것도 찾지 못했습니다. 그래서 나는 그것이 정말로 불가능하다고 생각합니다.

어쨌든 호기심 때문에 매크로로 무엇을하려고합니까?

3

당신은 자신의 주소를 사용하여 분리 정적 지역 변수를 말할 수 있습니다

  • 정적 변수

  • 지역 변수에 저장됩니다 중 하나 .bss라고 또는 .DATA 섹션 stored됩니다 스택

예를 들어 내 시스템의 다음 프로그램 출력

,451,515,
#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 

경고 :이 "트릭"을 사용하는 것은 권장하지 않습니다. 그것이 전부입니다 : 속임수, 가장 부적절한 상황에서 깨는 것. 매크로를 올바르게 문서화하고 그것을 사용하는 사람들이 오용의 여파를 처리하게하십시오.

+0

흥미로운 대답입니다. –

+0

이것이 항상 작동한다는 보장은 없습니다. – BiGYaN

+0

@BiGYaN : 결국 경고 ... – thkala

2

대부분의 C 라이브러리에서 사용하는 방식으로 간단하게 수행하십시오. 매크로가 정적 변수에 대해 작동하고 다른 것에 대한 동작이 정의되지 않았거나 예상치 못한 경우 일 수 있음을 사용자에게 알립니다.

strdup() 등의 NULL 포인터를 전달할 수있는 것처럼 세그 폴트가 발생하지만 아무런 영향을 미치지 않는 큰 문제는 없습니다.

관련 문제