用C语言实验全局变量和函数

时间:2022-08-24 16:15:11

I'm trying to understand how global variables and functions work in C. My program compiles and works fine with gcc, but does not compile with g++. I have the following files:

我正在尝试理解在c中全局变量和函数是如何工作的。我有以下文件:

globals.h:

上面:

int i;
void fun();

globals.c:

globals.c:

#include "stdlib.h"
#include "stdio.h"

void fun()
{
  printf("global function\n");
}

main.c:

c:

#include "stdlib.h"
#include "stdio.h"
#include "globals.h"

void myfun();

int main()
{

  i=1;

  myfun();

  return 0;
}

And finally, myfun.c:

最后,myfun.c:

#include "stdlib.h"
#include "stdio.h"
#include "globals.h"

void myfun()
{
  fun();
}

I get the following error when compiling with g++:

使用g++编译时,我得到如下错误:

/tmp/ccoZxBg9.o:(.bss+0x0): multiple definition of `i'
/tmp/ccz8cPTA.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

Any ideas why? I would prefer to compile with g++.

任何想法为什么?我更喜欢用g++来编译。

4 个解决方案

#1


6  

Every file you include globals.h from will define "int i".

每个文件都包含全局变量。h从将定义“int i”。

Instead, put "extern int i;" into the header file and then put the actual definition of "int i = 1;" in globals.c.

相反,将“extern int i”放入头文件中,然后将“int i = 1”的实际定义放在globals.c中。

Putting header guards around globals.h would be sensible too.

在全局栏上设置标题栏。h也是明智的。

Edit: In answer to your question its because a #include works kind of like a cut and paste. It pastes the contents of the included file into the c file that you are calling include from. As you include "globals.h" from main.c and myfun.c you define int i = 1 in both files. This value, being global, gets put into the table of linkable values. If you have the same variable name twice then the linker won't be able to tell which one it needs and you get the error you are seeing. Instead by adding extern on the front in the header file you are telling each file that "int i" is defined somewhere else. Obviously, you need to define it somewhere else (and ONLY in one place) so defining it in globals.c makes perfect sense.

编辑:在回答你的问题时,因为#include作品有点像剪切和粘贴。它将所包含文件的内容粘贴到正在调用include的c文件中。包括“全局。从主要h”。c和myfun。在两个文件中定义int i = 1。这个值是全局的,它被放到可链接值表中。如果你有两个相同的变量名,那么链接器就不能知道它需要哪个,你就会得到你看到的错误。相反,通过在头文件的前面添加extern,您是在告诉每个文件,在其他地方定义了“int i”。显然,您需要在其他地方(并且仅在一个地方)定义它,以便在全局中定义它。c意义非凡。

Hope that helps :)

希望帮助:)

#2


1  

I would add an include guard in your globals file

我将在全局文件中添加一个包含保护

#ifndef GLOBALS_H
#define GLOBALS_H

int i;
void fun();

#endif

Edit: Change your globals to be like this (using extern as the other answer describes)

编辑:将您的全局变量更改为如下所示(使用外观作为另一个回答所描述的)

globals.h

上面

extern  int i;
extern  void fun();

globals.c

globals.c

#include "stdlib.h"
#include "stdio.h"
int i;
void fun()
{
  printf("global function\n");
}

I compiled it with

我编译的

g++ globals.c main.c myfun.c

and it ran ok

它跑好了

#3


1  

Several things wrong here; several other things highly recommended:

几件事情错了;强烈推荐以下几点:

globals.h:

上面:


#ifndef GLOBALS_H
#define GLOBALS_H

extern int my_global;

#ifdef __cplusplus
extern "C" {
#endif 
void fun();
#ifdef __cplusplus
}
#endif 

#endif
/* GLOBALS_H */

globals.c:

globals.c:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

int my_global;

void fun()
{
  printf("global function: %d\n", my_global);
}

main.c:

c:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

void myfun();

int main()
{

  my_global=1;

  myfun();

  return 0;
}

void myfun()
{
  fun();
}
  1. You should declare "extern int myvar" in your header, and actually allocate "int myvar" in one and only one .c file.

    您应该在头中声明“extern int myvar”,并在一个且仅为一个.c文件中分配“int myvar”。

  2. You should include "globals.h" in every file that uses "myvar" - including the file where it's allocated.

    你应该包括“全局。h在每个使用“myvar”的文件中——包括分配它的文件。

  3. Especially if you're planning on mixing C and C++ modules, you should use 'extern "C"' to distinguish non-C++ functions.

    特别是如果您打算混合使用C和c++模块,您应该使用‘extern ' C’来区分非c++函数。

  4. System headers should be "#include <some_header.h>"; your own headers should use quotes (#include "myheader.h") instead.

    系统标题应该是“#include ”;你自己的头应该使用引号(#include“header.h”)代替。

  5. Short variable names like "i" might be OK for a strictly local variable (like a loop index), but you should always use longer, descriptive names whenever you can't avoid using a global variable.

    对于严格的局部变量(如循环索引)来说,像“i”这样的短变量名是可以的,但是当您无法避免使用全局变量时,应该始终使用更长的描述性名称。

  6. I added a "printf" for my_global.

    我为my_global添加了一个“printf”。

'Hope that helps!

“希望帮助!

#4


0  

I had this problem when porting some old C code to C++. The problem was it was a project that was connected to a database, and i wanted to port the database to c++ but not the rest. The database pulled in some C dependencies that couldn't be ported, so i needed the C code that overlapped both the database and the other project to compile in g++ as well as gcc...

我在将一些旧的C代码移植到c++时遇到了这个问题。问题是,这是一个连接到数据库的项目,我想将数据库移植到c++,而不是其他的。数据库引入了一些无法移植的C依赖项,因此我需要在g++和gcc中编译与数据库和其他项目重叠的C代码……

The solution to this problem is to define all variables as extern in the .h file. then when you compile in either gcc or g++ it will report symbols missing in the .c files. So edit the .c files in the error messages and insert the declaration into all the .c files that need the variables. Note: you may have to declare it in multiple .c files, which is what threw me and why I was stuck on this problem for ages.

这个问题的解决方案是将所有变量定义为.h文件中的extern。然后,当您在gcc或g++中编译时,它将报告.c文件中丢失的符号。因此,在错误消息中编辑.c文件,并将声明插入所有需要变量的.c文件中。注意:您可能需要在多个.c文件中声明它,这是我和为什么我在这个问题上纠缠了很久的原因。

Anyway this solved my problem and the code compiles cleanly under both gcc and g++ now.

无论如何,这解决了我的问题,代码现在可以在gcc和g++下进行干净的编译。

#1


6  

Every file you include globals.h from will define "int i".

每个文件都包含全局变量。h从将定义“int i”。

Instead, put "extern int i;" into the header file and then put the actual definition of "int i = 1;" in globals.c.

相反,将“extern int i”放入头文件中,然后将“int i = 1”的实际定义放在globals.c中。

Putting header guards around globals.h would be sensible too.

在全局栏上设置标题栏。h也是明智的。

Edit: In answer to your question its because a #include works kind of like a cut and paste. It pastes the contents of the included file into the c file that you are calling include from. As you include "globals.h" from main.c and myfun.c you define int i = 1 in both files. This value, being global, gets put into the table of linkable values. If you have the same variable name twice then the linker won't be able to tell which one it needs and you get the error you are seeing. Instead by adding extern on the front in the header file you are telling each file that "int i" is defined somewhere else. Obviously, you need to define it somewhere else (and ONLY in one place) so defining it in globals.c makes perfect sense.

编辑:在回答你的问题时,因为#include作品有点像剪切和粘贴。它将所包含文件的内容粘贴到正在调用include的c文件中。包括“全局。从主要h”。c和myfun。在两个文件中定义int i = 1。这个值是全局的,它被放到可链接值表中。如果你有两个相同的变量名,那么链接器就不能知道它需要哪个,你就会得到你看到的错误。相反,通过在头文件的前面添加extern,您是在告诉每个文件,在其他地方定义了“int i”。显然,您需要在其他地方(并且仅在一个地方)定义它,以便在全局中定义它。c意义非凡。

Hope that helps :)

希望帮助:)

#2


1  

I would add an include guard in your globals file

我将在全局文件中添加一个包含保护

#ifndef GLOBALS_H
#define GLOBALS_H

int i;
void fun();

#endif

Edit: Change your globals to be like this (using extern as the other answer describes)

编辑:将您的全局变量更改为如下所示(使用外观作为另一个回答所描述的)

globals.h

上面

extern  int i;
extern  void fun();

globals.c

globals.c

#include "stdlib.h"
#include "stdio.h"
int i;
void fun()
{
  printf("global function\n");
}

I compiled it with

我编译的

g++ globals.c main.c myfun.c

and it ran ok

它跑好了

#3


1  

Several things wrong here; several other things highly recommended:

几件事情错了;强烈推荐以下几点:

globals.h:

上面:


#ifndef GLOBALS_H
#define GLOBALS_H

extern int my_global;

#ifdef __cplusplus
extern "C" {
#endif 
void fun();
#ifdef __cplusplus
}
#endif 

#endif
/* GLOBALS_H */

globals.c:

globals.c:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

int my_global;

void fun()
{
  printf("global function: %d\n", my_global);
}

main.c:

c:


#include <stdlib.h>
#include <stdio.h>
#include "globals.h"

void myfun();

int main()
{

  my_global=1;

  myfun();

  return 0;
}

void myfun()
{
  fun();
}
  1. You should declare "extern int myvar" in your header, and actually allocate "int myvar" in one and only one .c file.

    您应该在头中声明“extern int myvar”,并在一个且仅为一个.c文件中分配“int myvar”。

  2. You should include "globals.h" in every file that uses "myvar" - including the file where it's allocated.

    你应该包括“全局。h在每个使用“myvar”的文件中——包括分配它的文件。

  3. Especially if you're planning on mixing C and C++ modules, you should use 'extern "C"' to distinguish non-C++ functions.

    特别是如果您打算混合使用C和c++模块,您应该使用‘extern ' C’来区分非c++函数。

  4. System headers should be "#include <some_header.h>"; your own headers should use quotes (#include "myheader.h") instead.

    系统标题应该是“#include ”;你自己的头应该使用引号(#include“header.h”)代替。

  5. Short variable names like "i" might be OK for a strictly local variable (like a loop index), but you should always use longer, descriptive names whenever you can't avoid using a global variable.

    对于严格的局部变量(如循环索引)来说,像“i”这样的短变量名是可以的,但是当您无法避免使用全局变量时,应该始终使用更长的描述性名称。

  6. I added a "printf" for my_global.

    我为my_global添加了一个“printf”。

'Hope that helps!

“希望帮助!

#4


0  

I had this problem when porting some old C code to C++. The problem was it was a project that was connected to a database, and i wanted to port the database to c++ but not the rest. The database pulled in some C dependencies that couldn't be ported, so i needed the C code that overlapped both the database and the other project to compile in g++ as well as gcc...

我在将一些旧的C代码移植到c++时遇到了这个问题。问题是,这是一个连接到数据库的项目,我想将数据库移植到c++,而不是其他的。数据库引入了一些无法移植的C依赖项,因此我需要在g++和gcc中编译与数据库和其他项目重叠的C代码……

The solution to this problem is to define all variables as extern in the .h file. then when you compile in either gcc or g++ it will report symbols missing in the .c files. So edit the .c files in the error messages and insert the declaration into all the .c files that need the variables. Note: you may have to declare it in multiple .c files, which is what threw me and why I was stuck on this problem for ages.

这个问题的解决方案是将所有变量定义为.h文件中的extern。然后,当您在gcc或g++中编译时,它将报告.c文件中丢失的符号。因此,在错误消息中编辑.c文件,并将声明插入所有需要变量的.c文件中。注意:您可能需要在多个.c文件中声明它,这是我和为什么我在这个问题上纠缠了很久的原因。

Anyway this solved my problem and the code compiles cleanly under both gcc and g++ now.

无论如何,这解决了我的问题,代码现在可以在gcc和g++下进行干净的编译。