Reputation: 442
I am designing an API and the key part of it is a struct returned by the API with lots of const members. Also, there are both const pointers and pointers to const variables. Inside the implementation I need to modify this struct. Currently, I have defined exactly the same struct but with dropped const keywords and a different name. Inside the API calls I just cast external struct to the internal one.
Is there any way to code in a better way? The current design is prone to errors if I modify one struct and forget about the other.
Upvotes: 2
Views: 2307
Reputation: 6126
Duplication is the root of all evil, so instead of duplicating the structure definition you could do something like this:
#ifndef CONST
#define CONST const
#endif
struct mystruct
{
CONST void * my_data;
};
Now you just define CONST
to be empty before including the header file in the private implementation.
However, like the other answers suggest, this is not a very good idea. First there's probably better and cleaner ways of acheiving what you want. Second this could lead to strange and unwanted results as the compiler may use the constness of the fields to optimize the code.
In short, I think you would be better off rethinking your API.
Upvotes: -1
Reputation: 21966
Just a note here: These field aren't really non writable.
You want to make them kinda "private" but every programmer can access them this way:
typedef struct
{
const int x;
}mystruct;
Then:
mystruct ms= {0};
*((int*)&(ms.x)) =4;
printf("%d",ms.x);
Because the const specifier just prevents programmers from modifying them at compile time.But at runtime the memory isn't readonly.
I still think that the const specifier is useful: if a good programmer sees it, says then I shouldn't access that field.If instead wants to make the smart guy access the fields and potentially risk an inconsistent state.
So if you are sure that these const field can be changed, at your place I would use this way.I know that pedantic programmer will not like it, I don't like it too but sometimes we gotta bypass this.
Upvotes: 0
Reputation: 41180
Use opaque structs and accessor functions
The opaque structs provide a name for your API, but no way to address the fields.
The accessor functions in your API provide whatever controlled access you like.
Upvotes: 5