Pointer to a const structure, can members still be modified?
Clash Royale CLAN TAG#URR8PPP
up vote
13
down vote
favorite
I have a structure which I want to pass to some external c code via some callback function that they register with my program. However, I want to pass that structure as read-only. My concern is that they can still modify the structures which I have pointer to inside the original structure that I pass. Explained with small example below:
struct s1
int a;
int b;
;
struct s2
int x;
struct s1 *y;
;
void f(const struct s2 *o)
//o->x=10; //error
o->y->a=20; //no error
o->y->b=30; //no error
int main()
struct s1 o1 = 10, 20;
struct s2 o2 = 30, &o1;
f(&o2);
So, How do I improve my code design so that they cannot modify anything w.r.t the structure I pass?
c
add a comment |Â
up vote
13
down vote
favorite
I have a structure which I want to pass to some external c code via some callback function that they register with my program. However, I want to pass that structure as read-only. My concern is that they can still modify the structures which I have pointer to inside the original structure that I pass. Explained with small example below:
struct s1
int a;
int b;
;
struct s2
int x;
struct s1 *y;
;
void f(const struct s2 *o)
//o->x=10; //error
o->y->a=20; //no error
o->y->b=30; //no error
int main()
struct s1 o1 = 10, 20;
struct s2 o2 = 30, &o1;
f(&o2);
So, How do I improve my code design so that they cannot modify anything w.r.t the structure I pass?
c
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
2
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36
add a comment |Â
up vote
13
down vote
favorite
up vote
13
down vote
favorite
I have a structure which I want to pass to some external c code via some callback function that they register with my program. However, I want to pass that structure as read-only. My concern is that they can still modify the structures which I have pointer to inside the original structure that I pass. Explained with small example below:
struct s1
int a;
int b;
;
struct s2
int x;
struct s1 *y;
;
void f(const struct s2 *o)
//o->x=10; //error
o->y->a=20; //no error
o->y->b=30; //no error
int main()
struct s1 o1 = 10, 20;
struct s2 o2 = 30, &o1;
f(&o2);
So, How do I improve my code design so that they cannot modify anything w.r.t the structure I pass?
c
I have a structure which I want to pass to some external c code via some callback function that they register with my program. However, I want to pass that structure as read-only. My concern is that they can still modify the structures which I have pointer to inside the original structure that I pass. Explained with small example below:
struct s1
int a;
int b;
;
struct s2
int x;
struct s1 *y;
;
void f(const struct s2 *o)
//o->x=10; //error
o->y->a=20; //no error
o->y->b=30; //no error
int main()
struct s1 o1 = 10, 20;
struct s2 o2 = 30, &o1;
f(&o2);
So, How do I improve my code design so that they cannot modify anything w.r.t the structure I pass?
c
edited Aug 10 at 7:24
asked Aug 10 at 7:12
Raman
1,5361230
1,5361230
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
2
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36
add a comment |Â
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
2
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
2
2
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
8
down vote
accepted
To properly handle this situation, you can only use forward declaration to hide members together with getter and setter functions.
Focus on code below and check:
struct s1
only has forward declaration so you can make a pointer to it instruct s2
.- Actual implementation of
struct s1
is inmylib.c
thus all members are only visible to your library and not to user. - Getters and setters are implemented to set/read the value to these hidden members as only your library has access to members, making it completely hidden from user.
- This forces him to use your functions.
mylib.h:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2
int x;
struct s1* y;
;
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */
mylib.c:
#include "mylib.h"
//Now implement structure
struct s1
int a, b;
;
//Make getter
int
get_a_from_s1(struct s2* s)
return s->y->a;
//Make setter
void
set_a_to_s1(struct s2* s, int a)
s->y->a = a;
main.c:
#include <stdio.h>
#include "mylib.h"
int main(void)
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %drn", a);
return 0;
Of course, please make sure that ->y
is not NULL
or you have undefined behavior.
2
For the record, this kind of design pattern with incomplete type ofstruct s1
in the header is called opaque type or opaque pointers.
â Lundin
Aug 10 at 9:41
add a comment |Â
up vote
5
down vote
You cannot. Even if you pass the struct s2
by value, you will get in the function a pointer to a non const struct s1
, simply because it is what s2
contains per its definition.
And once you have a pointer to a non const object you can change that object. What I mean here and what other answers mean, is that it is not a language problem - more exactly the language can nothing for you here - but a design problem. If for any reason it is not acceptable that the struct s1
can be changed from f
then you have to find a different design where you do not pass a non const pointer to it, be it member of a const struct or not. Here a simple way would be to pass the individual members:
void f(int x, const struct s1 *y)
y->a = 20; // error
It may not be what you expect, but it is the best I can say for C language.
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
add a comment |Â
up vote
4
down vote
You can change the second struct declaration like so:
struct s2
int x;
struct s1 const *y;
;
The added const
ensures that y is read-only.
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
 |Â
show 2 more comments
up vote
0
down vote
I would write another function that takes in a const struct s1 * to modify the values of s1.
add a comment |Â
up vote
0
down vote
In f()
, const struct s2 *o
means in the struct s2
being pointed to by o
, the values of its members ie, x
and y
cannot be changed.
With o->y->a=20
, you are not modifying the value of y
. You are just using that address to modify a member of the structure being pointed to by y
and y
's value, which is an address, remains the same.
So those 2 lines will give no error.
I could see no way to avoid this unless you could make the struct s2
definition to
struct s2
int x;
const struct s1 *y;
;
in which case y
is a pointer to a constant struct s1
.
See the spiral rule and visit the cdecl website.
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
To properly handle this situation, you can only use forward declaration to hide members together with getter and setter functions.
Focus on code below and check:
struct s1
only has forward declaration so you can make a pointer to it instruct s2
.- Actual implementation of
struct s1
is inmylib.c
thus all members are only visible to your library and not to user. - Getters and setters are implemented to set/read the value to these hidden members as only your library has access to members, making it completely hidden from user.
- This forces him to use your functions.
mylib.h:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2
int x;
struct s1* y;
;
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */
mylib.c:
#include "mylib.h"
//Now implement structure
struct s1
int a, b;
;
//Make getter
int
get_a_from_s1(struct s2* s)
return s->y->a;
//Make setter
void
set_a_to_s1(struct s2* s, int a)
s->y->a = a;
main.c:
#include <stdio.h>
#include "mylib.h"
int main(void)
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %drn", a);
return 0;
Of course, please make sure that ->y
is not NULL
or you have undefined behavior.
2
For the record, this kind of design pattern with incomplete type ofstruct s1
in the header is called opaque type or opaque pointers.
â Lundin
Aug 10 at 9:41
add a comment |Â
up vote
8
down vote
accepted
To properly handle this situation, you can only use forward declaration to hide members together with getter and setter functions.
Focus on code below and check:
struct s1
only has forward declaration so you can make a pointer to it instruct s2
.- Actual implementation of
struct s1
is inmylib.c
thus all members are only visible to your library and not to user. - Getters and setters are implemented to set/read the value to these hidden members as only your library has access to members, making it completely hidden from user.
- This forces him to use your functions.
mylib.h:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2
int x;
struct s1* y;
;
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */
mylib.c:
#include "mylib.h"
//Now implement structure
struct s1
int a, b;
;
//Make getter
int
get_a_from_s1(struct s2* s)
return s->y->a;
//Make setter
void
set_a_to_s1(struct s2* s, int a)
s->y->a = a;
main.c:
#include <stdio.h>
#include "mylib.h"
int main(void)
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %drn", a);
return 0;
Of course, please make sure that ->y
is not NULL
or you have undefined behavior.
2
For the record, this kind of design pattern with incomplete type ofstruct s1
in the header is called opaque type or opaque pointers.
â Lundin
Aug 10 at 9:41
add a comment |Â
up vote
8
down vote
accepted
up vote
8
down vote
accepted
To properly handle this situation, you can only use forward declaration to hide members together with getter and setter functions.
Focus on code below and check:
struct s1
only has forward declaration so you can make a pointer to it instruct s2
.- Actual implementation of
struct s1
is inmylib.c
thus all members are only visible to your library and not to user. - Getters and setters are implemented to set/read the value to these hidden members as only your library has access to members, making it completely hidden from user.
- This forces him to use your functions.
mylib.h:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2
int x;
struct s1* y;
;
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */
mylib.c:
#include "mylib.h"
//Now implement structure
struct s1
int a, b;
;
//Make getter
int
get_a_from_s1(struct s2* s)
return s->y->a;
//Make setter
void
set_a_to_s1(struct s2* s, int a)
s->y->a = a;
main.c:
#include <stdio.h>
#include "mylib.h"
int main(void)
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %drn", a);
return 0;
Of course, please make sure that ->y
is not NULL
or you have undefined behavior.
To properly handle this situation, you can only use forward declaration to hide members together with getter and setter functions.
Focus on code below and check:
struct s1
only has forward declaration so you can make a pointer to it instruct s2
.- Actual implementation of
struct s1
is inmylib.c
thus all members are only visible to your library and not to user. - Getters and setters are implemented to set/read the value to these hidden members as only your library has access to members, making it completely hidden from user.
- This forces him to use your functions.
mylib.h:
#ifndef __MYLIB_H
#define __MYLIB_H
//Create forward declaration only
//Implementation is in .c file
struct s1;
//Create user structure
struct s2
int x;
struct s1* y;
;
int get_a_from_s1(struct s2* s);
void set_a_to_s1(struct s2* s, int a);
#endif /* __MYLIB_H */
mylib.c:
#include "mylib.h"
//Now implement structure
struct s1
int a, b;
;
//Make getter
int
get_a_from_s1(struct s2* s)
return s->y->a;
//Make setter
void
set_a_to_s1(struct s2* s, int a)
s->y->a = a;
main.c:
#include <stdio.h>
#include "mylib.h"
int main(void)
struct s2 s;
int a;
....
s.y->a = 5; //error
//Set s1.a value from s2 structure
set_a_to_s1(&s, 10); //OK
//To view members of s1 inside s2, create member functions
a = get_a_from_s1(&s); //OK
printf("a: %drn", a);
return 0;
Of course, please make sure that ->y
is not NULL
or you have undefined behavior.
edited Aug 10 at 9:46
answered Aug 10 at 7:43
tilz0R
5,32711131
5,32711131
2
For the record, this kind of design pattern with incomplete type ofstruct s1
in the header is called opaque type or opaque pointers.
â Lundin
Aug 10 at 9:41
add a comment |Â
2
For the record, this kind of design pattern with incomplete type ofstruct s1
in the header is called opaque type or opaque pointers.
â Lundin
Aug 10 at 9:41
2
2
For the record, this kind of design pattern with incomplete type of
struct s1
in the header is called opaque type or opaque pointers.â Lundin
Aug 10 at 9:41
For the record, this kind of design pattern with incomplete type of
struct s1
in the header is called opaque type or opaque pointers.â Lundin
Aug 10 at 9:41
add a comment |Â
up vote
5
down vote
You cannot. Even if you pass the struct s2
by value, you will get in the function a pointer to a non const struct s1
, simply because it is what s2
contains per its definition.
And once you have a pointer to a non const object you can change that object. What I mean here and what other answers mean, is that it is not a language problem - more exactly the language can nothing for you here - but a design problem. If for any reason it is not acceptable that the struct s1
can be changed from f
then you have to find a different design where you do not pass a non const pointer to it, be it member of a const struct or not. Here a simple way would be to pass the individual members:
void f(int x, const struct s1 *y)
y->a = 20; // error
It may not be what you expect, but it is the best I can say for C language.
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
add a comment |Â
up vote
5
down vote
You cannot. Even if you pass the struct s2
by value, you will get in the function a pointer to a non const struct s1
, simply because it is what s2
contains per its definition.
And once you have a pointer to a non const object you can change that object. What I mean here and what other answers mean, is that it is not a language problem - more exactly the language can nothing for you here - but a design problem. If for any reason it is not acceptable that the struct s1
can be changed from f
then you have to find a different design where you do not pass a non const pointer to it, be it member of a const struct or not. Here a simple way would be to pass the individual members:
void f(int x, const struct s1 *y)
y->a = 20; // error
It may not be what you expect, but it is the best I can say for C language.
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
add a comment |Â
up vote
5
down vote
up vote
5
down vote
You cannot. Even if you pass the struct s2
by value, you will get in the function a pointer to a non const struct s1
, simply because it is what s2
contains per its definition.
And once you have a pointer to a non const object you can change that object. What I mean here and what other answers mean, is that it is not a language problem - more exactly the language can nothing for you here - but a design problem. If for any reason it is not acceptable that the struct s1
can be changed from f
then you have to find a different design where you do not pass a non const pointer to it, be it member of a const struct or not. Here a simple way would be to pass the individual members:
void f(int x, const struct s1 *y)
y->a = 20; // error
It may not be what you expect, but it is the best I can say for C language.
You cannot. Even if you pass the struct s2
by value, you will get in the function a pointer to a non const struct s1
, simply because it is what s2
contains per its definition.
And once you have a pointer to a non const object you can change that object. What I mean here and what other answers mean, is that it is not a language problem - more exactly the language can nothing for you here - but a design problem. If for any reason it is not acceptable that the struct s1
can be changed from f
then you have to find a different design where you do not pass a non const pointer to it, be it member of a const struct or not. Here a simple way would be to pass the individual members:
void f(int x, const struct s1 *y)
y->a = 20; // error
It may not be what you expect, but it is the best I can say for C language.
answered Aug 10 at 7:32
Serge Ballesta
72.6k955125
72.6k955125
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
add a comment |Â
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
Yes, I also think that passing all members one by one is the only way.
â Raman
Aug 10 at 7:36
add a comment |Â
up vote
4
down vote
You can change the second struct declaration like so:
struct s2
int x;
struct s1 const *y;
;
The added const
ensures that y is read-only.
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
 |Â
show 2 more comments
up vote
4
down vote
You can change the second struct declaration like so:
struct s2
int x;
struct s1 const *y;
;
The added const
ensures that y is read-only.
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
 |Â
show 2 more comments
up vote
4
down vote
up vote
4
down vote
You can change the second struct declaration like so:
struct s2
int x;
struct s1 const *y;
;
The added const
ensures that y is read-only.
You can change the second struct declaration like so:
struct s2
int x;
struct s1 const *y;
;
The added const
ensures that y is read-only.
answered Aug 10 at 7:19
memo
1,274314
1,274314
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
 |Â
show 2 more comments
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, But that way I myself can't modify y.
â Raman
Aug 10 at 7:19
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
Yes, you can if you cast it back! ((struct s1 *) (o->y))->b=30;
â memo
Aug 10 at 7:21
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
@It'scominghome One scenario would be if you want to publish it as part of an API or library and make sure that users of it don't change it accidentally.
â memo
Aug 10 at 7:23
1
1
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
@memo very ugly and may introduce undefined behavior.
â tilz0R
Aug 10 at 7:25
1
1
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
@tilz0R I just answered the question, not that I would recommend it
â memo
Aug 10 at 7:27
 |Â
show 2 more comments
up vote
0
down vote
I would write another function that takes in a const struct s1 * to modify the values of s1.
add a comment |Â
up vote
0
down vote
I would write another function that takes in a const struct s1 * to modify the values of s1.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I would write another function that takes in a const struct s1 * to modify the values of s1.
I would write another function that takes in a const struct s1 * to modify the values of s1.
answered Aug 10 at 7:36
George Wu
261
261
add a comment |Â
add a comment |Â
up vote
0
down vote
In f()
, const struct s2 *o
means in the struct s2
being pointed to by o
, the values of its members ie, x
and y
cannot be changed.
With o->y->a=20
, you are not modifying the value of y
. You are just using that address to modify a member of the structure being pointed to by y
and y
's value, which is an address, remains the same.
So those 2 lines will give no error.
I could see no way to avoid this unless you could make the struct s2
definition to
struct s2
int x;
const struct s1 *y;
;
in which case y
is a pointer to a constant struct s1
.
See the spiral rule and visit the cdecl website.
add a comment |Â
up vote
0
down vote
In f()
, const struct s2 *o
means in the struct s2
being pointed to by o
, the values of its members ie, x
and y
cannot be changed.
With o->y->a=20
, you are not modifying the value of y
. You are just using that address to modify a member of the structure being pointed to by y
and y
's value, which is an address, remains the same.
So those 2 lines will give no error.
I could see no way to avoid this unless you could make the struct s2
definition to
struct s2
int x;
const struct s1 *y;
;
in which case y
is a pointer to a constant struct s1
.
See the spiral rule and visit the cdecl website.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
In f()
, const struct s2 *o
means in the struct s2
being pointed to by o
, the values of its members ie, x
and y
cannot be changed.
With o->y->a=20
, you are not modifying the value of y
. You are just using that address to modify a member of the structure being pointed to by y
and y
's value, which is an address, remains the same.
So those 2 lines will give no error.
I could see no way to avoid this unless you could make the struct s2
definition to
struct s2
int x;
const struct s1 *y;
;
in which case y
is a pointer to a constant struct s1
.
See the spiral rule and visit the cdecl website.
In f()
, const struct s2 *o
means in the struct s2
being pointed to by o
, the values of its members ie, x
and y
cannot be changed.
With o->y->a=20
, you are not modifying the value of y
. You are just using that address to modify a member of the structure being pointed to by y
and y
's value, which is an address, remains the same.
So those 2 lines will give no error.
I could see no way to avoid this unless you could make the struct s2
definition to
struct s2
int x;
const struct s1 *y;
;
in which case y
is a pointer to a constant struct s1
.
See the spiral rule and visit the cdecl website.
answered Aug 10 at 7:38
J...S
3,2921929
3,2921929
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51780954%2fpointer-to-a-const-structure-can-members-still-be-modified%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Do you want to allow them to read some parameters? If not, you may use forward declaration approach to hide some members from public code, make it visible only in private section of your library. Based on your answer I will give you official answer.
â tilz0R
Aug 10 at 7:30
What you can do is define the struct in a .c file. From all header function you typedef a void* for your type and other functions that belong to a public api of you type. Then from the callback you cannot see the members and only use the public functions of the type.
â hetepeperfan
Aug 10 at 7:30
@tilz0R Yes, they should be able to read all the members. They'll take different actions depending on what the value of that member is.
â Raman
Aug 10 at 7:34
2
To fully hide, you will have to create getter functions in your library.
â tilz0R
Aug 10 at 7:36