const struct *

B

bill

I recently realized that I have a structure that I'd like to put more
protection on in the following sense: I'd like to modify

struct foo{
int *x;
} ;

to be:
struct foo {
const int *x;
}

I see only 2 choices (3 if I count not making the change):
1) modify the structure and all functions that initialize instances of
it
2) define struct const_foo {const int *x;}, change the formal
parameter list of all functions that used to take a const foo *
argument to take a const const_foo * instead, and cast all
calls.

I'm not particularly fond of either solution. #1 is aesthetically
appealing (ie, it's the proper thing to do), #2 would be much
faster to implement in this case, but seems to be a kludge.
It seems as if I'm implementing the const keyword to
make "const foo *" mean "const foo */w const *x" and
is pretty ugly.

Can anyone suggest another solution?
 
M

Madguy

are you sure that changing int *i to const int *i make any error? i
think it will not . it'll make errors only if you assing 'i' any value
twice.
 
B

bill

Madguy said:
are you sure that changing int *i to const int *i make any error? i
think it will not . it'll make errors only if you assing 'i' any value
twice.

Things won't even compile if i simply add "const". Consider
the following code:

typedef struct { int *x;} foo_t;

void foo(foo_t *x){ *x->x = 3;}

int main()
{
foo_t x;
foo(&x);
return 0;
}

If you simply make to foo_t.x a const, then foo() is
writing to a read-only location. I think I'm actually asking a
slightly
more generic question:

suppose I have
struct foo_s {
int *a, *b, *c;
};

I want 3 functions, A(), B(), and C() which each take
a struct foo_s as an argument. A will only modify *a,
B will only modify *b, and C will only modify *c.
I'd like to reflect those facts in the parameter list
with const. The only solution I see for that is to
delcare 3 different structure types with const in
the appropriate place, and then either cast the
parameter for each call, or specify the parameter
as a void * and cast it within each function.
 
C

Chris Dollin

bill said:
If you simply make to foo_t.x a const, then foo() is
writing to a read-only location. I think I'm actually asking a
slightly
more generic question:

suppose I have
struct foo_s {
int *a, *b, *c;
};

I want 3 functions, A(), B(), and C() which each take
a struct foo_s as an argument. A will only modify *a,
B will only modify *b, and C will only modify *c.
I'd like to reflect those facts in the parameter list
with const. The only solution I see for that is to
delcare 3 different structure types with const in
the appropriate place, and then either cast the
parameter for each call, or specify the parameter
as a void * and cast it within each function.

You could do the following:

void A( const struct foo_s *p, int **toAlter )
{
... look hard a *p, update *toAlter
}

....
A( &someStructFooS, &someStructFooS.a );

Similarly for B & C.
 
B

bill

bill said:
suppose I have
struct foo_s {
int *a, *b, *c;
};

I want 3 functions, A(), B(), and C() which each take
a struct foo_s as an argument. A will only modify *a,
B will only modify *b, and C will only modify *c.
I'd like to reflect those facts in the parameter list
with const. The only solution I see for that is to
delcare 3 different structure types with const in
the appropriate place, and then either cast the
parameter for each call, or specify the parameter
as a void * and cast it within each function.

That actually works very nicely, but it's not immediately
clear from the function declaration what's going on. The following
code won't compile, due to the illegal assignement (which is
desirable). However, the function declaration just has "void *"
and you have to look in the function to see what members
of the structure are constant. Any ideas on how to improve this?
(I'm not willing to simply declare the formal parameter of type
x_foo_t without casting all the calls, as I will not accept compile
time warnings. I am willing to do specific warning suppression,
but I don't think that's possible. (ie, tag the function with an
attribute indictating that this particular function shouldn't
generate that particular warning). Can that be done?)

typedef struct {
int *x;
int *y;
int *z;
} foo_t;

typedef struct { /* use this struct when only modifying *x */
int *x;
const int *y;
const int *z;
} x_foo_t;

void
mod_x(void *A)
{
x_foo_t *a = (x_foo_t*) A;
*a->x = 3;
*a->y = 3; /* compile time error!! */
}

int
main()
{
int a[1],b[1],c[1];
foo_t x;
x.x = a; x.y=b, x.z=c;
mod_x(&x);
printf("x=%d, y=%d, z=%d\n", *x.x, *x.y, *x.z);
return 0;
 
B

bill

Chris said:
You could do the following:

void A( const struct foo_s *p, int **toAlter )
{
... look hard a *p, update *toAlter
}

...
A( &someStructFooS, &someStructFooS.a );

Similarly for B & C.

I like that idea, but I can't seem to get around the compiler
warning that I'm discarding the qualifier. When I make the call:
A(&p, &p.x), attempting to alter p.x, I need to cast it as
A(&p, (int *)&p.x). That method makes it clearer from
the declaration, so that's a good thing. There's probably
no way to avoid the cast.... (eventually, the compiler warnings
will all get casted away....yeah, right)
 
C

Chris Dollin

bill said:
I like that idea, but I can't seem to get around the compiler
warning that I'm discarding the qualifier. When I make the call:
A(&p, &p.x), attempting to alter p.x, I need to cast it as
A(&p, (int *)&p.x). That method makes it clearer from
the declaration, so that's a good thing. There's probably
no way to avoid the cast.... (eventually, the compiler warnings
will all get casted away....yeah, right)

I suspect you've declared the struct as a const. You don't need to
to satisfy your request above starting "I want 3 functions, A(), B(),
and C()". Presumably there's more context than I know.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top