Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const correctness for structs with pointers

I have a struct which contains some pointers. I want the value of these to be unmodifiable. But simply writing const infront doesn't make the structs members unmutable

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
}

Can someone point me in the right direction.

EDIT:

So it would seem that there is no simple way of using the function prototype to tell that everything belonging to the struct should be unmodifiable

like image 551
monkeyking Avatar asked Nov 01 '12 16:11

monkeyking


People also ask

Can a pointer point to a const?

C++ Constant Pointers to constants: In the constant pointers to constants, the data pointed to by the pointer is constant and cannot be changed. The pointer itself is constant and cannot change and point somewhere else.

Does C have const correctness?

In C, C++, and D, all data types, including those defined by the user, can be declared const , and const-correctness dictates that all variables or objects should be declared as such unless they need to be modified.

Can const be applied on structure objects?

'const' as the word constant itself indicates means unmodifiable. This can be applied to variable of any data type. struct being a user defined data type, it applies to the the variables of any struct as well. Once initialized, the value of the const variables cannot be modified.

Can we use const inside structure?

You can const an entire struct. struct aStruct { int32_t a; uint64_t b; }; const struct aStruct someStructA = {. a = 3, . b = 4};


1 Answers

You can do it without typecasting by defining a const point type and a mutable point type, then use a transparent union:

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;

Then, you declare your function parameters using either the point or const_point type (never the mutable_point type).

point type object will transparently cast to a const_point type, but not the reverse. This allows you to have a greater degree of type safety.

See here for an example in gcc: http://toves.freeshell.org/xueg/

Note that transparent union was not supported in the last version of C++ I checked (not sure about the latest C++ standard) so you can expect portability issues.

It can also make the code harder to read, and maintain, especially if you have more complex struct. e.g.: you could have point type where either x or y is const, or you may need to embed your point structure into a another struct, e.g. rectangle, for which you might have to define multiple struct for multiple type depending on their constness.

All in all, I'm not sure it's always worth the extra trouble.

like image 166
Droopycom Avatar answered Oct 01 '22 01:10

Droopycom