为什么在这个初始化中`const`限定符会被丢弃?

时间:2016-02-14 08:43:14

标签: c const

我在行initialization discards ‘const’ qualifier from pointer target type中收到.grid_col = &c_ax_gd警告,即为指针分配地址表达式,指针是常量结构的一部分。

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限定符?

2 个答案:

答案 0 :(得分:4)

问题出在其他地方。即使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,则会丢弃const上的a限定符。这就是你的编译器警告你的。

答案 1 :(得分:1)

gconst,表示其所有成员均为const(包括grid_col)。因此grid_col是指向const的{​​{1}}指针,而struct color是指向&c_ax_gd的指针。

您正尝试使用const struct color指针初始化const struct color指针,这就是您收到警告的原因。

C99 6.5.16.1

  

两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有右侧指向的类型的所有限定符

如果您忽略该警告,如果您修改值struct color指向的话,您将获得未定义的行为。