簡體   English   中英

錯誤:初始化元素不是恆定的

[英]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_secondmy_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中進行了測試。

  • -std = c99 -pedantic可以正常編譯。
  • -std = c89 -pedantic發出警告。 “警告:初始化程序元素在加載時不可計算[默認啟用]”。

(我不確定這種情況下的標准之間的區別,所以我寧願不推測為什么它在C99而不是C89中起作用。可能與VLA有關嗎?)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM