c-编译器删除的配置变量



我正在尝试定义一组全局变量,这些变量将配置我的设备,在一个专用的.c文件中大约有10个,在编译时会定期更改(根据设备要求(,我希望这些变量都在这个单独的文件中,这样它们都可以很容易地更改。然后,这些变量在我的程序的各个文件中被调用。而且永远都是不变的只读。问题是我的编译器(用于PIC MCU的XC8(没有定义变量,因为它只能在文件中看到变量的一次使用,即使在整个程序中使用extern调用它。

config.h

unsigned int Global_A;
unsigned int Global_B;
void config(void);

config.c

void config(void)
{
unsigned int Global_A=987;
unsigned int Global_B=123;
}

prog_a.h

extern unsigned int Global_A;
extern unsigned int Global_B;
unsigned int var_A;
void prog_a(void);

prog_a.c

unsigned int var_A=0;
void prog_a(void);
{
var_A=Global_A+Global_B;
}

main.c

#include config.h
#include prog_a.h
void main(void)
{
while(1)
{
config();
prog_a();
}
}

因此,等价的var_a总是0,因为编译器已经取消了config.c,因为它看不到再次调用的变量。

我想答案对那些更精通的人来说是显而易见的,但我在网上找不到任何东西。当在中定义的文件中使用extern和globals时,我以前从未遇到过使用它们的任何问题。但我可能只是从根本上使用错误,所以请随意斥责我。

提前谢谢。

附言:如果不明显的话,这是一个示例代码来说明我的问题。

您的函数配置在函数的作用域中声明了两个新变量(它们的名称隐藏了全局变量的名称(。它们不存在于它之外的任何地方,给它们赋值也无济于事。如果你的目标是初始化全局,你需要这样做:

// config.h
extern unsigned int Global_A;
extern unsigned int Global_B;
void config(void);
// config.c
unsigned int Global_A;
unsigned int Global_B;
void config(void) {
Global_A=987;
Global_B=123;
}

使用extern关键字,需要声明变量一次(最好在头文件中(在对声明语句具有可见性的.c文件中定义。就是这样。在需要extern定义的变量的情况下,#include是发生声明语句的头文件。

还请注意,全局范围中定义extern变量(即不在函数中(也很重要。

config.h:

#include "prog_a.h"
//unsigned int Global_A;
//unsigned int Global_B;
void config(void);

main.c

#include config.h
#include prog_a.h
...
//suggest defining these here:
unsigned int Global_A=0;//define outside of function
unsigned int Global_B=0;
...

config.c

#include "prog_a.h"
...
void config(void)
{
Global_A=987;
Global_B=123;
}

您的全局变量都是int类型,为什么不直接使用#define呢?

将文件config.h更改为

#define Global_A 789    
#define Global_B 123

实际上,您不必声明任何int变量来保存这些值,此外,它们将是const且不可修改。


我们就是这样做的"回到过去";,但在过去的一二十年里,我看到越来越多的人将这些配置值实际存储在外部文本文件中

它可以是。INI、XML或JSON等,由您决定。

您只需创建不同的文件,比如Singapore.iniParis.iniAuckland.ini等,每个文件都包含一个键/值对。

例如

time_zone = X
population = Y

等等

然后,在main开始时,读取文件并存储值,但不存储在globals中,这是目前不受欢迎的。将它们读取到config.c本地的变量中,并使用config.c/h provode方法读取它们的值,例如GetTimeZone()GetPoulation()

不要担心任何代码大小或运行时的影响,因为任何优秀的编译器都会内联这些函数调用。

阅读";全局";外部文本文件中的配置值是您只需要构建一次软件。您不需要重建并为每个配置都有一个可执行文件,这就是您目前正在走的路。

首先,只需编辑文本文件或提供新文件,就可以更容易地测试软件(尤其是自动化测试(。

此外,由于您只有一个可执行文件,您可以将其发送给所有用户/客户,并为每个用户/客户提供一个定制的配置文件。你可以完全控制&只需更改配置文件即可更改软件的功能。你可能会想一想。

相关内容

  • 没有找到相关文章

最新更新