0

我正在尝试使用以下代码初始化 C 结构:

/* header file */

typedef struct _funky {
   int  func_id;  /* I know this should be intptr_t, but ignore for now ... */
   char func_name[MAX_FUNC_NAME_LEN];
} Funky;


double func1(double d1, double d2, double d3);
double func2(double d1, double d2, double d3);
double func3(double d1, double d2, double d3);
double func4(double d1, double d2, double d3);


/* .c file */
Funky fk[4] = {
                 {(int)func1, "func1"}, /* <- gcc barfs here ... */
                 {(int)func2, "func2"},
                 {(int)func3, "func3"},
                 {(int)func4, "func4"}
              };

当我尝试编译它(gcc 4.6.3)时,我收到以下错误:

error: initializer element is not constant
error: (near initializer for 'fk[0].func_id')

我该如何解决这个错误?

[[编辑]]

在与 ouah 简短交谈后,我找到了此错误的原因 - 它与用于初始化数组的函数定义有关。一些定义在不同的翻译单元中,而另一些则在不同的模块中。所有这些都意味着(IIUC)函数不会在编译时定义。

缺少编写初始化函数(这将需要现有代码中的大量 mod)我不确定如何解决这个问题 - 我也不确定它是如何在以前版本的 gcc 下编译的。

4

2 回答 2

1

函数定义对问题并不重要。不过,用于的类型func_id是。

考虑这段代码:

#include <stdint.h>
#define MAX_FUNC_NAME_LEN  6

typedef uintptr_t ptr_t;

typedef struct Funky
{
   ptr_t  func_id;  /* I know this should be intptr_t, but ignore for now ... */
   char func_name[MAX_FUNC_NAME_LEN];
} Funky;

double func1(double d1, double d2, double d3);
double func2(double d1, double d2, double d3);
double func3(double d1, double d2, double d3);
double func4(double d1, double d2, double d3);

Funky fk[4] = {
                 {(ptr_t)func1, "func1"}, /* <- gcc barfs here ... */
                 {(ptr_t)func2, "func2"},
                 {(ptr_t)func3, "func3"},
                 {(ptr_t)func4, "func4"}
              };

如所写,使用uintptr_t,这可以在 Mac OS X 10.8.4(64 位编译)上的 GCC 4.8.1 下干净地编译。更改ptr_tto的类型,int您会收到一堆警告。问题是 64 位地址常量不适合 32 位int,因此加载程序必须生成代码来截断地址,这使得它们不够恒定。使用 32 位编译,使用的代码也可以int干净地编译。

所以,使用足够大的类型(uintptr_t推荐),你会没事的。“我知道应该是intptr_t,但暂时忽略”评论是您麻烦的根源;不要忽视它。

于 2013-08-21T07:52:03.453 回答
1
typedef _funky {
   int  func_id;  /* I know this should be intptr_t, but ignore for now ... */
   char func_name[MAX_FUNC_NAME_LEN];
} Funky;

这里缺少一个struct关键字。

还:

Funky fk[3] = {
                 {(int)func1, "func1"}, /* <- gcc barfs here ... */
                 {(int)func2, "func2"},
                 {(int)func3, "func3"},
                 {(int)func4, "func4"}
              };

您的数组中有3元素,但您使用初始化程序对其进行4初始化。

正如评论中所指出的,将函数指针转换为 aint可能是一个坏主意。绝对不能保证函数指针值适合int对象。

于 2013-08-20T22:09:04.127 回答