繁体   English   中英

初始化结构数组(编译器错误:初始化元素不是常量)

[英]Initializing an array of structs (compiler error: initializer element is not constant)

我正在尝试使用以下代码初始化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下编译的。

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初始值设定项初始化它。

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

函数定义对问题不重要。 但是,用于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_t的类型更改为int ,您会收到一堆警告。 问题是64位地址常量不适合32位int ,因此加载器必须生成代码来截断地址,这使得它们不够恒定。 使用32位编译,使用int的代码也可以干净地编译。

所以,使用足够大的类型(建议使用uintptr_t ),你就可以了。 “我知道它应该是intptr_tintptr_t忽略”评论是你麻烦的根源; 不要忽视它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM