在头文件中使用“extern const”使全局变量只读

时间:2014-12-31 16:54:27

标签: c api api-design header

我正在尝试使用GCC,并发现您可以在头文件中声明变量const,但在实现文件中保持它们是可变的。

编辑:这实际上不起作用,请查看我自己的答案。

header.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

header.c:

int global_variable = 17;

这使global_variable可修改,但const可修改为包含header.h的每个文件。

#include "header.h"

int main(void)
{
    global_variable = 34; /* "header.h" prevents this type of assignment. */
    return 0;
}

这种技术是否在实践中使用?

人们经常建议使用get - 函数来在C语言中构建接口时检索全局状态。对此方法有什么优势吗?

对我来说,这种方法似乎更加清晰,并且每次有人试图访问global_variable时都没有额外的函数调用开销。

4 个答案:

答案 0 :(得分:3)

这两种方法都在实践中使用,但大多数情况下的最佳做法是避免全局变量和静态。

注意:您的问题标记为C和C ++,这是C ++方法。

更好的方法是创建一个包含" global"状态并将其传递给否则需要全局变量和常量的函数。这被称为"上下文。"

上下文对象可以使用适当的信息隐藏来控制谁可以更新其状态,验证其状态等,就像任何其他对象一样。此外,它完全避免了对全局变量的需求,这是一种反模式。

答案 1 :(得分:2)

get函数允许稍后插入新逻辑(例如验证)。如果你从一个全局变量开始并稍后发现你需要新逻辑,那么添加一个get函数就是一个重大改变。

答案 2 :(得分:2)

这实际上无效。

举个例子。

header.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

header.c:

#include "header.h"

int global_variable; // Here will the compiler complain!

由于intconst int不兼容,因此无法编译。我自己的测试工作的唯一原因是因为我在“header.c”中 NOT 包含“header.h”。

答案 3 :(得分:0)

这是一种前C ++ 11的做法,可能会有一些陷阱:实际上它依赖于链接器来维持分辨率。如果所有值都很简单,那么这不是一个大问题,但是如果某个值不是POD并且依赖于其他值,因为源不指定链接顺序,这可能会暴露给“全局初始化惨败”。

内部头文件有时可能采用更简单的方法

static constexpr int global_constant = xx;

static关键字使每个独立翻译单元的global_constant本地化,避免只需定义一次“通用全局对象”。

这种方法也与“仅头文件库”兼容,这是通用代码必须的。