簡體   English   中英

如何將sizeof運算符應用於函數指針並初始化結構?

[英]How to apply the sizeof operator to a function pointer and initialize a structure?

后面的代碼會產生錯誤:在聲明和初始化用戶struct變量的行上, 初始化器元素在編譯時不是恆定的

#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;
}

在主函數中移動初始化可以解決此問題,但是我想了解為什么? 結構初始化有任何限制嗎?

而且,如您所見,我創建了一個tmp user_struc變量來獲取函數指針的大小,因為我無法以一種更簡潔的方式來做到這一點。 我怎樣才能解決這個問題 ?

第一個問題:

“結構初始化是否有任何限制?”

C要求靜態存儲持續時間恆定的聚合類型的初始化程序是恆定的:

(C99,6.7.8p4)“具有靜態存儲持續時間的對象的初始化程序中的所有表達式應為常量表達式或字符串文字。”

請注意,在C89中,即使聚合類型的對象具有自動存儲時間,初始化器也必須是常量表達式(在C99中不再是這種情況)。

第二個問題:

“此外,如您所見,我創建了一個tmp user_struc變量來獲取指向函數指針的指針的大小,因為我無法以更簡潔的方式做到這一點。”

您可以使用您的user對象來計算成員的大小:

sizeof (user.pred_skip_func)

或使用C99復合文字,如果您尚未聲明任何結構類型的對象:

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

正如@ouah所指出的那樣,問題在於pred_skip_func不是恆定值。 編譯器抱怨,因為user具有靜態存儲持續時間,這意味着其按位表示將在鏈接時“放入”可執行映像中。 為了使鏈接器知道此表示, pred_skip_func的值必須為常數。

但是,您可以非常輕松地為struct成員指定“合理的默認”常量值:

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

您可以為函數指針使用typedefs ,如下所示。

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); 
    .....
}

這將增加程序的可讀性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM