2016-02-14 107 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

相关问题