[英]error: initializer element is not constant
#include <stdio.h>
typedef struct {
int a;
int b;
int c;
} FIRST_T;
typedef struct {
int x;
int y;
int z;
FIRST_T *p;
} SECOND_T;
typedef struct {
int a1;
int a2;
int a3;
FIRST_T *q;
}THIRD_T;
const FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}};
const FIRST_T p2[]={{4,5,12},{7,8,9}};
const SECOND_T my_second[]=
{
{1,2,3,p1},
{4,5,6,p2}
};
const THIRD_T my_third[] = {{1,2,3,my_second[1].p},{4,5,6,my_second[0].p}};
int main() {
//const THIRD_T my_third[] = {{1,2,3,my_second[1].p},{4,5,6,my_second[0].p}};
printf("%d %d %d %d \n",
my_third[0].a1,
my_third[0].a2,
my_third[0].a3,
my_third[0].q[1].c);
}
我知道如果我在函數作用域中初始化my_third,它的工作原理就像“在C中,具有靜態存儲持續時間的對象(例如在文件作用域中聲明的對象只能用常量表達式初始化)”否則它給我:
錯誤:初始化元素不是常量new.c:41:錯誤:(靠近“ my_third [0] .q”的初始化)
現在我的問題是:在不移動函數內部表達式的情況下,有什么變通辦法嗎? 這些代碼在我的代碼中很多地方都使用過,因此我無法動彈。
如果您需要更多信息,請告訴我。
丑陋的方式:
#include <stdio.h>
struct first_t {
int a;
int b;
int c;
};
struct second_t {
int x;
int y;
int z;
const struct first_t *p;
};
struct third_t {
int a1;
int a2;
int a3;
const struct first_t *q;
};
const struct first_t p1[] = {
{1, 2, 3},
{3, 4, 5},
{6, 7, 8}
};
const struct first_t p2[] = {
{4, 5, 12},
{7, 8, 9}
};
const struct second_t my_second[] = {
{1, 2, 3, p1},
{4, 5, 6, p2}
};
const struct third_t my_third[] = {
{1, 2, 3, (const struct first_t*)&my_second[1].p},
{4, 5, 6, (const struct first_t*)&my_second[0].p}
};
int main(void) {
fprintf(stdout,
"PRNT: %d %d %d %d\n",
my_third[0].a1,
my_third[0].a2,
my_third[0].a3,
my_third[0].q[1].c
);
return 0;
}
得到:
/* gcc -Wall -Wextra -pedantic -std=c89 -ggdb -o bad fmts.c && ./bad
*
* PRNT: 1 2 3 4
*
* */
關於什么
const THIRD_T my_third[] = {{1,2,3,p2},{4,5,6,p1}};
因為這正是您將獲得的價值?
為了使更改更容易,您可以包裝一個圖層,例如
const FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}};
const FIRST_T p2[]={{4,5,12},{7,8,9}};
#define first_p p1
#define second_p p2
const SECOND_T my_second[]=
{
{1,2,3,first_p},
{4,5,6,second_p}
};
const THIRD_T my_third[] = {{1,2,3,second_p},{4,5,6,first_p}};
然后只需更改#define
即可使my_second
和my_third
保持同步。
另一種選擇是將THIRD_T
更改為包含SECOND_T
而不是FIRST_T
。 然后(也許)使用#define
來簡化訪問:
typedef struct {
int a1;
int a2;
int a3;
SECOND_T *qq;
}THIRD_T;
#define q qq->p
以便
my_third->q
變得有效
my_third->qq->p
。
typedef struct {
int x;
int y;
int z;
FIRST_T *p;
} SECOND_T;
當聲明此struct const
的變量時,其所有成員都將成為const
,就像它們存儲在ROM中一樣。 int const x;
, int const y;
對於指針,這意味着它變為FIRST_T * const p;
。 即,指向非恆定數據的const指針。 指向類型仍然不是const
! 我懷疑這就是您遇到問題的原因。
{1,2,3,p1},
p1是數組類型,並且會衰減為const FIRST_T p1* const
(指向常量數據的常量指針)。 您嘗試將其分配給FIRST_T * const p;
(指向非恆定數據的恆定指針)。 要解決此問題,請嘗試將類型聲明為
typedef struct {
int x;
int y;
int z;
const FIRST_T *p;
} SECOND_T;
typedef struct {
int a1;
int a2;
int a3;
const FIRST_T *q;
} THIRD_T;
已在MinGW,GCC 4.6.2中進行了測試。
(我不確定這種情況下的標准之間的區別,所以我寧願不推測為什么它在C99而不是C89中起作用。可能與VLA有關嗎?)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.