简体   繁体   English

使结构不可变有意义吗?

[英]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和处理SIGINTstop_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM