【发布时间】:2014-07-02 13:17:35
【问题描述】:
我正在使用 GCC C 为嵌入式产品开发硬件抽象库。在库中,有一个变量对于链接库的应用程序应该是只读的,但可以从编译单元中修改定义它。
是否有一种标准的、可接受的方式来声明整数(在库头文件中),这将允许应用程序读取变量中的值,但如果尝试生成代码,则告诉编译器生成错误写回它? 例如,如果我将一个 function 声明为:
extern void foo(int const bar);
...然后调用者被允许传递一个局部变量:
int bar = 0;
foo(bar);
...但是如果函数声明尝试写入bar:
void foo(int const bar)
{
bar = 99;
}
...那么编译器适时报错:assignment of read-only location 'bar'。
将const 放在名称前的语法似乎并不像应用于函数参数那样应用于变量,并且下面的两行似乎实际上是等效的:
extern const int x;
extern int const y;
...因为将 y 定义为 int y; 会导致错误:'y' 的类型限定符冲突,正如我所期望的那样,将 x 定义为 int x;。
我知道我可以通过声明和定义一个返回值(只能用作 r 值)的访问器函数来解决这个问题。
我在这里阅读了许多相关问题,但我发现没有一个问题可以为 C(相对于 C++ 或 C#)提供明确的答案:
C — Accessing a non-const through const declaration
请有人指出我如何实现它的示例的方向,或者确认我怀疑它在语法上无法实现?
【问题讨论】:
-
不要在定义变量的翻译单元中包含声明
const变量的头文件?或者在定义变量的翻译单元中有一个预处理器宏#define,并在头文件中对其进行条件检查? -
@JoachimPileborg 这两个问题都在于嵌入式编译器希望在微控制器的闪存中找到一个常量值,但实际变量将存储在内部 RAM 中。 IE。如果它通过链接器,这两个引用将指向两个完全不同的物理内存位置。
-
“声明和定义访问函数”不是“绕过”,而是最佳实践。你为什么不这样做呢?请参阅 Jack Ganssle 的文章 A Pox on Globals 了解一些合适的教育。至关重要的是,链接器可能会决定在 ROM 或 MMU 保护的只读 RAM 中定位常量,这可能与您的计划相悖。
-
@Clifford 这是一篇有趣的文章,Phil Gillaspy 的回复也同样有趣,其本质是“变量应该在代码中的一个且仅一个位置修改”。全局变量确实会导致问题。如果 C 提供了一种语法方式来实现 C# 中可用的
int MyVar {get; private set;}模式,那就太好了。
标签: c embedded constants declaration extern