2012-08-03 3 views
0

다음 코드는 오류를 생성합니다. 사용자 구조체 변수를 선언하고 초기화하는 줄에서 이니셜 라이저 요소가 컴파일시에 이 상수가 아닙니다.sizeof 연산자를 함수 포인터에 적용하고 구조체를 초기화하는 방법은 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 

struct user_s { 
    char *name; 
    void (*(*pred_skip_func))(int); 
}; 

void f1 (int skip) { 
    printf("I am f1\n"); 
} 

void f2 (int skip) { 
    printf("I am f2\n"); 
} 

void (*(*pred_skip_func))(int); 
struct user_s user = {"Manu", pred_skip_func}; 

int main(void) { 

    struct user_s tmp; 
    pred_skip_func = malloc(sizeof(tmp.pred_skip_func) * 2); 
    pred_skip_func[0] = f1; 
    pred_skip_func[1] = f2; 

    int i; 
    for (i = 0; i < 2; i++) { 
     (*(user.pred_skip_func)[i]) (i); 
    } 
    return EXIT_SUCCESS; 
} 

주 기능의 초기화를 이동하면 문제가 해결되지만 그 이유를 알고 싶습니다. 구조 초기화에 대한 제한이 있습니까?

더 자세히 살펴보면 tem user_struc 변수를 만들어 내 포인터를 함수 포인터로 가져올 수 있기 때문에 더 깨끗한 방식으로이 작업을 수행 할 수 없었습니다. 이 문제를 어떻게 해결할 수 있습니까?

답변

2

첫 번째 질문 :

"구조 초기화에 어떤 제한이 있습니까?"

C는 상수 정적 저장 기간이 집계 유형에 대한 초기화가 필요합니다 집계 유형의 개체가 자동 저장 기간을 한 경우에도 C89의 intializers이 될 상수 식을 한 것으로

(C99, 6.7.8p4) "All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals."

주 (이 더 이상 C99에서는 그렇지 않습니다.

두 번째 질문 :

"당신이 볼 수 있듯이 나는 깨끗한 방법으로이 작업을 수행 할 수 없습니다 때문에 더 이상, 나는 포인터를 함수 내 포인터의 크기를 얻을 수있는 TMP user_struc 변수를 만들었습니다."

당신은 멤버의 크기를 계산하기 위해 user 객체를 사용할 수 있습니다

sizeof (((struct user_s) {0}).pred_skip_func) 
+0

이 예제에서 struct 사용자는 정적 저장소가 있습니까? 나를 위해. 그래서 나는 명확하게 이해하지 못합니다. –

+2

@ManuelSelva : 파일 범위에서 선언 된 변수에는 * 정적 저장 기간 *이 있습니다. – Jon

+0

확인. 따라서 전역 변수를 정적 변수로 선언해도 "저장 기간"에는 영향을 미치지 않지만 어떻게 호출할까요? –

2

: 당신이 구조 유형의 객체를 선언하지 않은 경우

sizeof (user.pred_skip_func) 

또는 리터럴 C99 화합물을 사용 @ouah가 지적한 것처럼, pred_skip_func은 상수 값이 아닙니다. user에는 정적 저장 기간이 있으므로 컴파일러에서 불만을 토로합니다. 즉, 비트 단위 표현은 링크 할 때 실행 가능 이미지에서 "baked"될 것입니다. 이 표현을 링커에 알리려면 pred_skip_func의 값은 상수 여야합니다.

그러나, 당신은 매우 쉽게 구조체의 멤버에 대해 "제정신 기본"상수 값을 지정할 수 있습니다 : 당신은 아래와 같이 함수 포인터에 대한 typedefs 갈 수

struct user_s user = {"Manu", 0}; 
1

.

typedef void (*pfunc_type)(int); 

struct user_s 
{  
    char *name;  
    pfunc_type *pred_skip_func; 
}; 

..... 

int main (void) 
{ 
    ..... 
    pred_skip_func = (pfunc_type *)malloc(sizeof(pfunc_type) * 2); 
    ..... 
} 

이렇게하면 프로그램의 읽기 가능성이 높아집니다.

관련 문제