[英]Does it make any sense to make struct immutable?
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. 自从我从高级Java进入C语言以来,我们没有像
const
这样的类型查询器才能使类型不可变,因此我们必须将其所有成员声明为final,并确保成员本身是不可变的。
By contract, in C we have type quialifier const
. 根据合同,在C中,我们有类型quaalifier
const
。
To be more specific, let me provide an example I'm currently stuck with. 更具体地说,让我提供一个我目前坚持的示例。 I have the following
我有以下
application.h
: 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. 我不确定如何定义
application_t
结构。 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. 它的唯一目的是做actaul奔跑与
run_application
和处理SIGINT
与stop_application
执行正常关闭,再经过stop_application
返回到调用release_app(struct application_t*)
以释放内存。
I have the following case to choose: 我有以下几种情况可供选择:
I . 我 Immutable
application_t
不变的
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... 但是创建这样一个不可变的结构无论如何都要进行
memcpy
调用...
II . 二 。 Mutable
application_t
while create application will be declared as 创建应用
application_t
时可变的application_t
将声明为
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. 可以,但是我想在
stop_application
返回后释放由struct application_t*
指向的内存。 Releasing struct application_t*
means that appliaction_t
is not really const
. 释放
struct application_t*
意味着appliaction_t
不是真正的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. 需要对投
const
湖。
Releasing struct application_t* means that appliaction is not really const
释放结构application_t *意味着应用并不是真正的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. 客户端代码无法对其进行更改,并且无论如何都应将其移交给
release_app
之后再使用它。 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
). 它在整个生命周期中都是
const
,并且如果release_app
被指向const的指针接受,则它在语义上是正确的(只需在release_app
内部进行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? 因为当
create_app
为该结构分配空间并对其进行初始化时,它不是其中的const
,不是吗? The const
is added later as part of a contract. const
将在以后作为合同的一部分添加。 So accepting a const pointer in release_app
is just following the same contract you already established. 因此,在
release_app
接受const指针只是遵循您已经建立的相同协定。 The fact the API pair knows the storage can be mutated doesn't break the contract. API对知道存储可以被更改的事实并没有违反合同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.