变量重新定义,嵌入式c

变量重新定义,嵌入式c,c,header,embedded,redefinition,C,Header,Embedded,Redefinition,我正在从事一个嵌入式c项目,在全局变量重新定义方面遇到了问题 我已经将函数声明和定义拆分为几个.h和.c文件。其中许多函数需要访问全局变量,这些变量在global_vars.h中定义。因此,在头文件的开头,在#ifndef#define部分中,“global_vars.h”。如果我没有,就像你想象的那样,我会得到一堆未定义的变量错误 然而,即使global_vars.h具有“ifndef”global_vars_h#定义#endif,我得到所有全局变量的重新定义错误。我的猜测是,当链接器尝试链接

我正在从事一个嵌入式c项目,在全局变量重新定义方面遇到了问题

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

然而,即使global_vars.h具有“ifndef”global_vars_h#定义#endif,我得到所有全局变量的重新定义错误。我的猜测是,当链接器尝试链接各种对象文件时,它会看到重新定义,因为所有“blah_blah.h”文件中都包含“global_vars.h”。不过,我的理解是,如果。。。处理这个问题

有什么是我忽略的吗


提前感谢

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

在global_vars.h中,您应该有如下声明:

extern int some_global;
您不允许有:

int some_global;
如果在global_vars.h中有定义,那么,是的,它们将在链接时被多次定义,因为包含global_vars.h的每个.c文件都有自己定义的每个定义变量

当然,
extern
globals的所有定义都必须在某个.c文件中。通常,哪个.c文件并不重要。通常,所有全局变量定义都在一个名为(惊喜!)global_vars.c的文件中


因此,请确保global_vars.h中没有任何全局变量定义,这样您就会处于良好状态。

在h文件中定义全局变量不是一个好主意。更好的是,如果你在C或C++文件中这样做,你就可以把其他文件中包含的H文件和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 .....

}
#include globals.h

char SomeOtherFunc(void)
{
  AGLOBAL+=10; // ok cause its defined by globals.h
  // do 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文件

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

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

}
#include globals.h

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

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

与C函数一起使用extern。默认情况下,C函数的声明和定义前面有“extern”。这意味着,即使我们不在C函数的声明/定义中使用extern,它仍然存在。 例如,当我们写作时

int foo(int arg1, char arg2);
开头有一个隐藏的外部代码,编译器如下处理

extern int foo(int arg1, char arg2);
C函数的定义也是如此(C函数的定义意味着编写函数体)。因此,每当我们定义一个C函数时,函数定义的开头就有一个外部变量。由于声明可以执行任意次数,并且定义只能执行一次,因此我们可以注意到,可以在多个C/H文件或单个C/H文件中多次添加函数声明。但我们只注意到函数的实际定义一次(即仅在一个文件中)。当extern将可视性扩展到整个程序时,只要函数声明已知,就可以在整个程序的任何文件中的任何位置使用(调用)函数。(通过知道函数的声明,C编译器知道函数的定义存在,并继续编译程序)。 所有这些都是关于C函数的外部

  • 声明可以执行任意次数,但定义只能执行一次

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

  • 因为默认情况下,函数在整个程序中都是可见的。函数声明/定义中不需要使用extern。它的使用是多余的

  • 当extern与一个变量一起使用时,它只被声明而不被定义

  • 作为一个例外,当使用初始化声明外部变量时,它也被视为变量的定义


  • 您需要在标题中声明变量,并且只在一个源文件中定义它们。您的
    global_vars.h
    文件应该将所有变量声明为
    extern
    ,然后在单独的模块中实际定义它们。我猜你没有这么做?你是对的。我会试试这个,谢谢你的旁注,如果你在你的项目中有一个“globals”文件,并且在文件范围内声明了非常量globals,它通常表明整个程序设计有一些根本性的错误。