![](/img/trans.png)
[英]Compiler error initializing array of structs in C (array must be initialized with a brace-enclosed initializer)
[英]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_t
但intptr_t
忽略”評論是你麻煩的根源; 不要忽視它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.