0

以下代码生成错误: 在编译时声明和初始化用户结构变量的行上,初始化元素不是常量。

#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 变量来获取指向函数指针的指针的大小,因为我无法以更简洁的方式执行此操作。我怎样才能解决这个问题 ?

4

3 回答 3

2

第一个问题:

“结构初始化有什么限制吗?”

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) 
于 2012-08-03T11:32:51.263 回答
2

正如@ouah 指出的那样,问题在于这pred_skip_func不是一个恒定值。编译器抱怨是因为user具有静态存储持续时间,这意味着它的按位表示将在链接时“烘焙”到可执行映像中。为了让链接器知道这个表示,for 的值pred_skip_func必须是一个常数。

但是,您可以很容易地为 struct 成员指定一个“合理的默认”常量值:

struct user_s user = {"Manu", 0};
于 2012-08-03T11:38:17.473 回答
1

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

这将增加程序的可读性。

于 2012-08-03T12:44:54.910 回答