2016-02-14 105 views
3

我得到initialization discards ‘const’ qualifier from pointer target type警告.grid_col = &c_ax_gd行,即分配一個地址表達式的指針,這是一個恆定結構的一部分。 爲什麼`const`限定符在這個初始化中被丟棄了?

struct color { 
    double r; 
    double g; 
    double b; 
    double a; 
}; 
struct graph { 
    double origin[2]; 
    double dim[2]; 
    double scale[2]; 
    double grid_line_width; 
    double axes_line_width; 
    struct color *grid_col; 
    struct color *axes_col; 
}; 

int main(void) { 
    static const struct color c_ax_gd = {0.5, 0.5, 0.5, 1}; 
    static const double h = 600, w = 800; 
    const struct graph g = { 
      .origin = {w/2, h/2}, 
      .dim = {w, h}, 
      .scale = {w/20, h/20}, 
      .grid_line_width = 0.5, 
      .axes_line_width = 1, 
      .grid_col = &c_ax_gd, 
      .axes_col = &c_ax_gd 
    }; 
    .... 
} 

我發現標準

更多緯度被允許用於初始化常量表達式在C99以下。這樣的常量表達式應,或評估於下列中的一種:

  • 算術常量表達式,
  • 空指針常量,
  • 一個地址常量,或
  • 一個地址常量一個對象類型加上或減去一個整數常量表達式。

地址常量是一個空指針,一個指向一個左值指定靜態存儲持續時間,或指針的功能指示符的對象;應當明確地使用一元&操作者或整數常數澆鑄到指針類型,或隱式地通過使用陣列或功能類型的表達式來創建

我的問題是,並不意味着&c_ax_gd是一個地址常量?如果是這樣,在初始化器中爲常量結構使用地址常量如何丟棄const限定符?

回答

3

問題出在別的地方。即使structconst,如果它具有指針作爲成員,那些指針指向的對象也不會自動const。你可以從下面的例子中看到。

struct example { 
    int * p; 
}; 

int 
main() 
{ 
    /* const */ int a = 1; 
    const struct example s = {&a}; 
    *(s.p) = 2; 
    return 0; 
} 

因此,如果您取消註釋/* const */a地址分配給s.p,你丟棄在aconst預選賽。這就是你的編譯器警告你的。

1

gconst,這意味着它的所有成員都是const(包括grid_col)。所以grid_colconst指向struct color的指針,並且&c_ax_gd是指向const struct color的指針。

您正在嘗試使用struct color指針初始化const struct color指針,這就是爲什麼您會收到警告。

C99 6.5.16.1

兩個操作數是指向兼容類型的合格或不合格的版本,並且類型由左指出,有類型的所有預選賽由右

指出,

如果您忽略該警告,則只需修改grid_col指向的值即可得到未定義的行爲。

+0

不會將結構聲明爲'const'使其成員爲'const'? – Samik

+1

@Samik是的,它的所有成員都是const。問題是如果這些成員中的一些是指針,它們只是const指針(你不能改變指針;沒有限制適用於它們指向的值)。你可以檢查這個:http://stackoverflow.com/questions/10091825/constant-pointer-vs-pointer-on-a-constant-value – martinkunev

+0

謝謝,完全錯過了一個,我多麼愚蠢。 upvoted你的答案。 – Samik

相關問題