const指针结构的正确性

时间:2012-11-01 16:36:12

标签: c constants const-correctness

我有一个包含一些指针的结构。我希望这些价值不可修改。但是简单地编写const infront并不会使结构成员不可改变

typedef struct{
  int *x;
  int *y;
}point;

void get(const  point *p,int x, int y){
  p->x[0]=x;//<- this should not be allowed
  p->y[0]=y;//<- this should not be allowed
}

有人能指出我正确的方向。

编辑:

所以似乎没有简单的方法来使用函数原型来告诉属于结构的所有东西都应该是不可修改的

4 个答案:

答案 0 :(得分:9)

您可以通过定义const点类型和可变点类型而不进行类型转换来实现,然后使用透明联合:

typedef struct{
    const int *  x;
    const int *  y;
} const_point;

typedef struct{
    int *  x;
    int *  y;
} mutable_point;

typedef union __attribute__((__transparent_union__)) {
    const_point cpoint;
    mutable_point point;
} point;

然后,使用point或const_point类型声明函数参数(从不使用mutable_point类型)。

点类型对象将透明地转换为const_point类型,但不是相反的。 这使您可以获得更高程度的类型安全性。

请参阅此处了解gcc中的示例:http://toves.freeshell.org/xueg/

请注意,我检查的最后一个C ++版本不支持透明联合(不确定最新的C ++标准),因此您可以预期可移植性问题。

它还可以使代码更难以阅读和维护,特别是如果您有更复杂的结构。 例如:你可以有点类型,其中x或y是const,或者你可能需要将你的点结构嵌入到另一个结构中,例如:矩形,您可能必须根据其常量为多个类型定义多个结构。

总而言之,我不确定这总是值得额外的麻烦。

答案 1 :(得分:3)

如果我正确理解了您的问题,您希望将整个struct对象的constness自动传播到该struct成员指向的对象。即如果struct对象不是const,则数组应该是可修改的,而如果struct对象是const,则数组不应该是可修改的。

如果是这样,那么,遗憾的是,它在C语言中无法实现。

在C ++中,可以通过强制用户使用访问者成员函数来访问数据成员(而不是直接访问数据成员)来完成。但在C语言中根本无法完成。

答案 2 :(得分:2)

解释你需要建立什么,写作时

point str;

point *p=&str;

此处 p是指向str 的指针,其类型为

当你将它声明为const时,它意味着p是一个常量指针。这不会限制结构可能包含的指针。

如果要在结构中应用const ness,则必须将结构内的指针定义为const

typedef struct{
   const int *  x;
   const int *  y;
}point;

再次推回家我的观点将参数声明为

    void get(point * const  p,int x, int y) 
   //Constant Pointer ( *to prevent p from pointing to anything else*)

    //    AND

   //Make the pointers inside point structure constant
   //( *to prevent the int pointers x & y from pointing to anything else*)

如果它所指向的结构也是常量使用

      void get(const point * const p, int x, int y)
     //Constant Pointer to constant structure 

答案 3 :(得分:1)

那是因为你更改了另一个指针所指向的内存内容而不是p

p指向包含指向int的2个指针的结构。您不会更改p指向的内存,而是更改另一个内存区域。所以编译器就可以了。

       +----------+
p ->   |    x     |  -> wherever  
       +----------+
       |    y     |  -> another place in memory
       +----------+

const内容p不可继承。如果你写了p->a = array;那么编译器就会抱怨。 const只是一个合同,表示你不会通过该指针改变内存。