2011-06-16 39 views
2

我正在开发嵌入式c项目,并且遇到了全局变量重定义方面的问题。变量重定义,嵌入式c

我已经将函数声明和定义分解为一些.h和.c文件。许多这些函数需要访问global_vars.h中定义的全局变量。因此,在头文件的开头,在#ifndef,#define部分,“global_vars.h”中。如果我不这样做,就像你可能想象的那样,我会得到一堆未定义的变量错误。

但是,即使global_vars.h具有#ifndef _GLOBAL_VARS_H_ #define ... #endif,我也会得到所有全局变量的重定义错误。我的猜测是,当链接器尝试链接各种对象文件时,它会在所有“blah_blah.h”文件中看到#include“global_vars.h”的重新定义。不过,我的理解是#ifndef ...处理这个问题。

有什么我可以忽略?

在此先感谢

+1

您需要在头文件中声明变量,并且只在一个源文件中定义它们。 – forsvarir 2011-06-16 21:27:55

+4

您的'global_vars.h'文件应该将所有变量声明为'extern',然后在一个单独的模块中实际定义它们。我猜你不会这样做? – 2011-06-16 21:29:00

+0

你是对的。我会试试这个,谢谢 – Trey 2011-06-16 21:37:01

回答

7

的链接永远看不到任何东西在global_vars.h文件,永远,除非 - 坏消息! - 某些全局变量实际上是在该文件中定义的。 global_vars.h应该只保存这些全局变量的声明,从不(几乎不会)定义它们。

在global_vars.h,你应该有这样的声明:

extern int some_global; 

你不准有:

int some_global; 

如果您有global_vars.h定义的话,是的,他们”在链接时会被多次定义,因为#includes global_vars.h中的每个.c文件都会有自己的每个已定义变量的定义。

当然,extern全局的所有定义都必须在的一些 .c文件中。通常它与.c文件无关。通常所有的全局变量定义都在一个名为(surprise!)global_vars.c的文件中。

因此,请确保global_vars.h中没有任何全局变量定义,并且状态良好。

0

在H文件中定义全局变量不是一个好主意。如果你在C或C++文件中这样做,并且在其他模块中包含H文件并将这些全局变量作为外部函数,那更好。 像这样>>>

我模块的C文件

unsigned short int AGLOBAL = 10; // definer and initializer 

void MyFunc(void) 
{ 
    AGLOBAL+=1; // no need to include anything here cause is defined above 
    // more ..... 

} 

我的.h文件globals.h

// this is to include only once 
#ifndef MYH 
#define MYH 
extern unsigned short int AGLOBAL; // no value in here! 

#endif 

其他模块的C文件

#include globals.h 

char SomeOtherFunc(void) 
{ 
    AGLOBAL+=10; // ok cause its defined by globals.h 
    // do more.... 
} 
1

所以让我先说extern关键字适用于C变量(数据对象)和C函数。基本上,extern关键字扩展了C变量和C函数的可见性。这可能就是它被命名为extern的原因。

使用extern与C函数。默认情况下,C函数的声明和定义具有前缀“extern”。这意味着即使我们没有将C函数的声明/定义用于extern,它也存在于那里。例如,我们写的时候。

int foo(int arg1, char arg2); 

有一个extern出现在开始隐藏,编译器将其视为如下。

extern int foo(int arg1, char arg2); 

与C函数的定义(C函数的定义意味着写入函数的主体)的情况一样。因此,无论何时我们定义一个C函数,都会在函数定义的开头出现一个extern。由于声明可以进行多次,定义只能进行一次,所以我们可以注意到函数的声明可以添加到几个C/H文件或多个单独的C/H文件中。但是我们注意到函数的实际定义只有一次(即仅在一个文件中)。而且由于extern扩展了整个程序的可视性,只要函数的声明已知,就可以在整个程序的任何文件中的任何位置使用(调用)函数。 (通过了解函数的声明,C编译器知道函数的定义存在,并继续编译该程序)。这就是所有关于C函数的extern。

  1. 声明可以做任何次数,但定义只有一次。

  2. “extern”关键字用于扩展变量/函数()的可见性。

  3. 由于函数在程序中默认是可见的。函数声明/定义中不需要使用extern。它的使用是多余的。

  4. 当extern与变量一起使用时,只声明未定义。

  5. 作为一个例外,当一个extern变量被初始化声明时,它也被当作变量的定义。