簡體   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