使结构不可变有意义吗?

时间:2019-02-03 08:37:06

标签: c struct const

由于我来自高级Java的C语言,那里没有像const这样的类型查询器,所以为了使类型不可变,我们必须声明其所有成员为final,并确保成员本身是不可变的

根据合同,在C中,我们有类型quialifier const

更具体地说,让我提供一个我目前坚持的例子。我有以下

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*);

我不确定如何定义application_t结构。它的唯一目的是使用run_application运行actaul并使用SIGINT处理stop_application以执行正常关闭,然后在stop_application返回后调用release_app(struct application_t*)来执行释放内存。

我有以下几种情况可供选择:

I 。不变的application_t

struct application_t{
    void (*const run_application)(struct application_t*);
    void (*const stop_application)(struct application_t*);
}

我认为这很好,因为一旦创建应用程序就不应对其进行修改。但是创建这样一个不变的结构无论如何都要进行memcpy调用...

II 。创建应用程序时将变量application_t声明为

const struct application_t* create_app(const struct application_config_t);

这很好,但是我想在struct application_t*返回后释放stop_application所指向的内存。释放struct application_t*意味着appliaction_t并不是真正的const。用法如

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

需要强制使用const进行强制转换。

1 个答案:

答案 0 :(得分:3)

  

发布struct application_t *意味着应用并不是真正的常量

实际上是。客户端代码无法对其进行更改,并且无论如何都应将其移交给release_app之后再使用。它在整个生命周期中都是const,并且如果release_app被指向const的指针接受,则它在语义上是正确的(只需在release_app内部进行强制转换)。

为什么我说这在语义上是正确的?因为当create_app为该结构分配空间并对其进行初始化时,它不是其中的const了吗? const稍后会作为合同的一部分添加。因此,在release_app中接受const指针只是遵循您已经建立的相同协定。 API对知道存储可以更改的事实并没有违反合同。