Since I came to C from higher level Java where we don't have type quialifiers like const
in order to make a type immutable we have to declare all its members final and be sure the members are immutable by themselves.
By contract, in C we have type quialifier const
.
To be more specific, let me provide an example I'm currently stuck with. I have the following
application.h
:
struct application_config_t{
int poll_interval;
int compression_ratio;
//other config parameters
};
struct application_t{ //This structure make me confused
void (*run_application)(struct application_t*);
void (*stop_application)(struct application_t*);
};
struct application_t* create_app(const struct application_config_t);
void release_app(struct application_t*);
I'm not sure about how to define application_t
structure. Its only purpose is to do the actaul run with run_application
and to handle SIGINT
with stop_application
to perform graceful shutdown and then after stop_application
returns to call release_app(struct application_t*)
to free the memory.
I have the following case to choose:
I . Immutable application_t
struct application_t{
void (*const run_application)(struct application_t*);
void (*const stop_application)(struct application_t*);
}
I think this is fine because once created an application should not be modified. But creation of such an immutable structure will entail memcpy
call anyway...
II . Mutable application_t
while create application will be declared as
const struct application_t* create_app(const struct application_config_t);
This would be fine, but I want to release the memory pointed to by struct application_t*
after stop_application
returns. Releasing struct application_t*
means that appliaction_t
is not really const
. And usage like
struct application_config_t cfg;
//...
const struct application_t *app_ptr = create_app(cfg);
(app_ptr -> run_application)(app_ptr);
release_app((struct application_t *) app_ptr); //const cast
would require cast against const
ness.
Releasing struct application_t* means that appliaction is not really const
Actually it is. The client code could not mutate it, and should not be using it further after handing it over to release_app
anyway. It is const
throughout its lifetime, and if release_app
accepts by a pointer to const, it will be semantically correct (just do the cast inside release_app
).
Why do I say it will be semantically correct? Because when create_app
allocates space for the structure and initializes it, it isn't const
in there, is it? The const
is added later as part of a contract. So accepting a const pointer in release_app
is just following the same contract you already established. The fact the API pair knows the storage can be mutated doesn't break the contract.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.