将struct中的成员初始化为外部函数的方向

时间:2013-09-14 00:23:30

标签: c gcc

让我说我有这个

typedef struct qwerty {
    void *f;
} qwerty_t;

我想要这样做

static qwerty_t x    = {
    .f = (void *)some_external_function
};

我得到error: initializer element is not constant因为(如果我理解的话)我正在编译时some_external_function的方向未知。

如果这不是错误的正确解释,请解释是什么。

另外,如何将.f初始化为该函数的方向?

2 个答案:

答案 0 :(得分:3)

从评论到问题:

  
      
  1. 您没有显示some_external_function的声明?例如,如果它本身是一个函数指针,而不是一个实际的函数,那么你就会得到那个错误。 - Jonathan Leffler

  2.   
  3. 的确,你是对的。我正是这样做的。 - alexandernst

  4.   

我不确定它是否明确,但是... Mac OS X 10.8.4上的GCC 4.8.1接受此代码确定:

extern int some_external_function(int, int);

typedef struct qwerty {
    void *f;
} qwerty_t;

static qwerty_t x    = {
    .f = (void *)some_external_function
};

int main(void)
{
    int i = 1;
    int j = 2;
    int (*f)(int, int) = (int (*)(int, int))x.f;
    return f(i, j);
}

int some_external_function(int i, int j)
{
    return i + j;
}

当像这样编译'额外挑剔'时,你会得到一些警告:

$ gcc -std=c99   -Wall -Wextra -pedantic fp.c -o fp  
fp.c:8:14: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
         .f = (void *)some_external_function
              ^
fp.c: In function ‘main’:
fp.c:15:26: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
     int (*f)(int, int) = (int (*)(int, int))x.f;
                          ^
$

警告非常准确 - 但POSIX声明函数指针的大小必须与数据指针的大小相同(而C标准允许它们不同)。没有-pedantic,就没有警告。

将代码拆分为两个文件,一个定义为xmain(),另一个定义为some_external_function(),编译和链接不会产生错误,也不会产生新警告。

答案 1 :(得分:2)

这很可能是因为您要为x定义静态关键字。基本上,C要求您将静态存储与常量表达式或值相关联。即使是下面这么简单的事情也会给你带来同样的错误:

int main() {
   int y = 10;
   static int z = y;
}