2009-09-23 83 views
2

使用V1.8的z/OS XL C编译器,使用INFO(ALL)抬高式警告,我得到下面的代码的4号线以下警告:不允许在类型“const int ** const”和“int **”之间初始化,为什么?

WARNING CCN3196 Initialization between types "const int** const" and "int**" 
       is not allowed. 


1 int foo = 0; 
2 int *ptr = &foo; 

3 const int * const fixed_readonly_ptr = ptr; 

4 const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

我不能换我头部为什么我得到这个警告。如果我可以分配一个int指针指向const int(第3行)的const指针,那么为什么我不能将int指针的地址分配给const指针指向const int的指针?我错过了什么?

注意上面的代码是一个瘦身的例子,只是显示了我在少量代码中遇到的问题。真正的上下文是,我有一个const指针指向struct(struct s ** const)的指针,并将它作为参数传递给一个函数,它的参数被定义为const指针指向const struct的const指针(const struct s **常量)。这是因为该函数不会修改struct中的数据(因此是第一个const),并且它不会修改始终保存传入地址(因此为第二个const)的指针参数。指针指向的值可能会改变方式(这就是为什么**之间没有第三个常量)。

+0

帕维尔和查尔斯已经充分说明了为什么编译器警告我。我赞成你们两位,但是从Charles的角度来看,Charles把它分解了下来(尽管两个答案都非常相似,并说明了为什么会发布警告)。 – 2009-09-24 02:47:50

回答

3

的C规则是,你可以将指针转换的东西到一个指向const的指针,但是某些东西必须是完全相同的类型,包括链下的const和volatile限定。

这一规则的理由是,如果这两条线的第二被允许:

int *ptr; 

const int ** const fixed_ptr_to_readonly_ptr = &ptr; 

然后这可以被用来打破类型安全性而不铸造。

const int i = 4; 

// OK, both sides have type const int * 
*fixed_ptr_to_readonly_ptr = &i; 

// the value of fixed_ptr_to_readonly_ptr is still &ptr 
// the value of ptr is now &i; 

*ptr = 5; 

// oops, attempt to change the value of i which is const 
5

这是一种类型的安全违规行为。考虑这个代码(我拖着const张望了一下,以明确是否适用于指针或指针对象,但语义这意味着同样的事情):

int* p = 0; 
int const** pp = &p; // presumably ok 

int const c = 123; 
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue 

*p = 666; // okay, *p is int lvalue 

// wait, so we just changed the value of (const) c above, with no const_cast! 
相关问题