2016-10-28 5 views
0

복잡한 구조의 필드를 초기화하는 매크로를 작성하려고합니다. 이 구조체에서, 어떤 멤버는 때로는 실제 주소로 초기화하려고하는 포인터이고 때로는 NULL으로 초기화됩니다. 다음과 같은 구조를 단순화 할 수있다 :이 정적 포인터에 대한 초기화가 유효하지 않은 이유는 무엇입니까?

#define INIT_STRUCT(x) {&(x)} 

및 사용은 다음과 같습니다 : 매크로에서

typedef struct { 
int * p; 
} MYSTRUCT; 

내 첫 번째 패스이었다 내가 초기화 할 때

static int foo; 
static MYSTRUCT struct1 = INIT_STRUCT(foo); 

이 잘 작동 실제 포인터로 이동하지만 다음은 작동하지 않습니다.

static MYSTRUCT struct2 = INIT_STRUCT(NULL); 

{&(NULL)}으로 컴파일되고 컴파일러 (justifiably)는 &의 플래그를 오류로 사용하기 때문에 발생합니다. 나는 &을 매크로 몸체의 일부가 아닌 인수의 일부로 선택할 수 있다는 것을 알고 있지만, 내 경우에는 편리하지 않으며, 컴파일러가 이기기 때문에 받아 들일 수 없다. 그래서 나는 더 똑똑 해 지려고 노력했다. 매크로의 다음 두 번째 버전 :

static void * NOTHING; 
#define INIT_STRUCT(x) {&NOTHING == &(x) ? NULL : &(x)} 

사용에

MYSTRUCT struct1 = INIT_STRUCT(foo); 
MYSTRUCT struct2 = INIT_STRUCT(NOTHING); 

그러나 "초기화가 일정하지"라는 컴파일러 시위. &NOTHING == &(x)1 == 2으로 바꾸면 오류가 없으므로 조건의 형식은 문제가되지 않습니다. 한편, &NOTHING&(foo)은 이니셜 라이저로서 유효합니다.

내 "더 똑똑한"매크로를 무효화하는 데 컴파일러가 맞습니까? foo에 대한 인수의 일부로 &을 쓰는 것을 제외하고는 다른 해결책이 있습니까?

컴파일러는 Microsoft Visual Studio C 2010 Ultimate입니다.

+4

로 사용된다 (X) {(X)}'와 INIT_STRUCT (foo는)'로 사용 '? 코드의 독자에게 더 투명하게 될 것이며, 물론 'NULL'을 사용하여 문제를 해결할 것입니다. –

+1

@Someprogrammerdude가 말한 것 외에 2 개의 매크로를 정의 할 수도 있습니다. 하나는 일반적인 경우이고 다른 하나는 특별한 경우입니다. 매크로가 너무 융통성이 없으며 나중에 다른 문제가 발생할 수 있으므로 매크로를 "똑똑하게"사용하는 것은 피해야합니다. – user694733

답변

1

이것을 단순화하고 사용할 수 있습니다.

#define INIT_STRUCT(str, x) {str -> p = x} 

왜 단순히 #DEFINE의 INIT_STRUCT`과`INIT_STRUCT` 매크로를 정의하지

INIT_STRUCT(struct1, foo); 
INIT_STRUCT(struct2, NULL); 
+0

이것은 할당이지 초기화가 아닙니다. 따라서'const' 변수에서는 작동하지 않습니다. – user694733

관련 문제