我在行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
限定符?
答案 0 :(得分:4)
问题出在其他地方。即使struct
为const
,如果它有指针作为成员,那些指针指向的对象也不会自动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)
g
为const
,表示其所有成员均为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
指向的话,您将获得未定义的行为。