在不同的文件中使用全局变量

时间:2021-04-13 16:45:42

So what i'm trying to do is using a variable from file1.c in file2.c. I've seen some answers already on here but I still get the same error as before. (error: variably modified at file scope)

所以我要做的是在file2.c中使用file1.c中的变量。我已经在这里看到了一些答案,但我仍然得到了和以前一样的错误。 (错误:在文件范围内进行了可变修改)

What I have on file1.c is something like this:

我在file1.c上的内容是这样的:

extern int num = 0;
struct abc *do_something(int n){
    num = n;
}
/*more code below*/

now I wanted to use num on file2.c. I have this:

现在我想在file2.c上使用num。我有这个:

#include <something.h> /*which has file1.h inside*/
int num;
struct list_t list[num]; /*error here*/

/*code that uses the initialized list below*/

I tried using something like #define test_num num that it didn't work either. I need the list to be "global" on file2 so I can use it in different methods.

我尝试使用#define test_num num这样的东西,它也没用。我需要列表在file2上是“全局”的,所以我可以在不同的方法中使用它。

3 个解决方案

#1


1  

You have two problems actually. The first which relates to your error is that the value of num is unknown when the compiler sees the declaration of your array list. The compiler doesn't know anything from any other translation unit (a source file with all included header files), all it knows is the translation unit it's currently working on.

实际上你有两个问题。第一个与您的错误有关的是,当编译器看到数组列表的声明时,num的值是未知的。编译器不知道任何其他翻译单元(包含所有包含头文件的源文件)的任何内容,它只知道它正在处理的翻译单元。

The second problem is more theoretical, and it's that the size of an array is fixed at the time of compilation, and changing the variable num at run-time will not change the size of the array.

第二个问题更具理论性,而且数组的大小在编译时是固定的,在运行时更改变量num不会改变数组的大小。

The first problem can be solved by moving the initialization of num to the translation unit where it actually is used. Oh and not initialize it as zero, a zero-sized array is not of much use.

第一个问题可以通过将num的初始化移动到实际使用它的转换单元来解决。哦,并没有将其初始化为零,零大小的数组没有多大用处。

The second problem can be solved by using pointers and dynamic allocation using malloc and realloc.

第二个问题可以通过使用指针和使用malloc和realloc的动态分配来解决。

#2


1  

The error in the list declaration is nothing to do with the definition of the global num, although that is also incorrect, but rather that you are attempting to dimension an array with with a variable outside of a function. Which is illegal and also nonsense. The value of num when list is instantiated is non-deterministic, and even if num were were initialised first, you'd be declaring an array of zero length.

列表声明中的错误与全局num的定义无关,尽管这也是错误的,而是您尝试使用函数外部的变量对数组进行维度。这是非法的,也是胡说八道。列表实例化时num的值是非确定性的,即使num先被初始化,你也要声明一个零长度的数组。

You have the extern in the wrong place. In file1.c you should have:

你有一个错误的地方。在file1.c中你应该有:

int num = 0 ;

while in file2.c:

在file2.c中:

extern int num ;

Normally you would place the extern declaration in a header file - this allows the compiler to check the types match between declaration and definition, and allows the correct and consistent declaration to be used in multiple files with a single point of maintenance should you change the type for example.

通常,您将extern声明放在头文件中 - 这允许编译器检查声明和定义之间的类型匹配,并允许在多个文件中使用正确且一致的声明,如果您更改类型,则只需一个维护点例如。

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

extern int num ;  // Declaration

#endif

// file1.c
#include "file1.h"

int num = 0 ; // Definition/Instantiation

// file2.c
#include "file1.h"
int f()
{
    return num ;  // Use file1::num
}

All that said really don't use globals at all. It is bad practice and unnecessary. Rather:

所有这一切真的根本不使用全局变量。这是不好的做法和不必要的。而是:

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

  void setNum( int n ) ;
  int getNum() ;

#endif

// file1.c
#include "file1.h"

static int num = 0 ; // Protected by file scope
void setNum( int n ) { num = n ; }
int getNum() { return n ; }

// file2.c
#include "file1.h"

int f()
{
    setNum( getNum() + 1 ) ;  // Increment num (example r/w access)
    return getNum() ;
}

This has a number of advantages, including:

这有许多优点,包括:

  • The set function can range check or validate
  • set函数可以进行范围检查或验证
  • A variable may be made read-only by external functions (by omitting a setter)
  • 变量可以通过外部函数变为只读(通过省略setter)
  • A variable may be made write-only by external functions (by omitting a getter)
  • 变量可以由外部函数写入(通过省略getter)
  • Nothing can take a reference to the variable and monkey with it in an uncontrolled manner.
  • 没有什么可以以不受控制的方式引用变量和猴子。
  • In debug all accesses to the variable can be trapped by break-points in the access functions.
  • 在调试中,对变量的所有访问都可以被访问函数中的断点捕获。

Further reading A Pox on Globals (related to embedded systems, but no less applicable generally.

进一步阅读Globals上的A Pox(与嵌入式系统有关,但一般情况下也不例外)。

#3


0  

To share a global variable between two files you should be aware that the variable belongs to the source file which has it declared without "extern". As such, it should also be initialized in that source file. Using extern tells your compiler it will find the variable from some other object file at link time.

要在两个文件之间共享一个全局变量,您应该知道该变量属于没有“extern”声明的源文件。因此,它也应该在该源文件中初始化。使用extern告诉编译器它会在链接时从其他一些目标文件中找到该变量。

As Joachim wrote you also have a problem with your array using this global variable.

正如Joachim所写,使用此全局变量时,您的数组也存在问题。

#1


1  

You have two problems actually. The first which relates to your error is that the value of num is unknown when the compiler sees the declaration of your array list. The compiler doesn't know anything from any other translation unit (a source file with all included header files), all it knows is the translation unit it's currently working on.

实际上你有两个问题。第一个与您的错误有关的是,当编译器看到数组列表的声明时,num的值是未知的。编译器不知道任何其他翻译单元(包含所有包含头文件的源文件)的任何内容,它只知道它正在处理的翻译单元。

The second problem is more theoretical, and it's that the size of an array is fixed at the time of compilation, and changing the variable num at run-time will not change the size of the array.

第二个问题更具理论性,而且数组的大小在编译时是固定的,在运行时更改变量num不会改变数组的大小。

The first problem can be solved by moving the initialization of num to the translation unit where it actually is used. Oh and not initialize it as zero, a zero-sized array is not of much use.

第一个问题可以通过将num的初始化移动到实际使用它的转换单元来解决。哦,并没有将其初始化为零,零大小的数组没有多大用处。

The second problem can be solved by using pointers and dynamic allocation using malloc and realloc.

第二个问题可以通过使用指针和使用malloc和realloc的动态分配来解决。

#2


1  

The error in the list declaration is nothing to do with the definition of the global num, although that is also incorrect, but rather that you are attempting to dimension an array with with a variable outside of a function. Which is illegal and also nonsense. The value of num when list is instantiated is non-deterministic, and even if num were were initialised first, you'd be declaring an array of zero length.

列表声明中的错误与全局num的定义无关,尽管这也是错误的,而是您尝试使用函数外部的变量对数组进行维度。这是非法的,也是胡说八道。列表实例化时num的值是非确定性的,即使num先被初始化,你也要声明一个零长度的数组。

You have the extern in the wrong place. In file1.c you should have:

你有一个错误的地方。在file1.c中你应该有:

int num = 0 ;

while in file2.c:

在file2.c中:

extern int num ;

Normally you would place the extern declaration in a header file - this allows the compiler to check the types match between declaration and definition, and allows the correct and consistent declaration to be used in multiple files with a single point of maintenance should you change the type for example.

通常,您将extern声明放在头文件中 - 这允许编译器检查声明和定义之间的类型匹配,并允许在多个文件中使用正确且一致的声明,如果您更改类型,则只需一个维护点例如。

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

extern int num ;  // Declaration

#endif

// file1.c
#include "file1.h"

int num = 0 ; // Definition/Instantiation

// file2.c
#include "file1.h"
int f()
{
    return num ;  // Use file1::num
}

All that said really don't use globals at all. It is bad practice and unnecessary. Rather:

所有这一切真的根本不使用全局变量。这是不好的做法和不必要的。而是:

// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE

  void setNum( int n ) ;
  int getNum() ;

#endif

// file1.c
#include "file1.h"

static int num = 0 ; // Protected by file scope
void setNum( int n ) { num = n ; }
int getNum() { return n ; }

// file2.c
#include "file1.h"

int f()
{
    setNum( getNum() + 1 ) ;  // Increment num (example r/w access)
    return getNum() ;
}

This has a number of advantages, including:

这有许多优点,包括:

  • The set function can range check or validate
  • set函数可以进行范围检查或验证
  • A variable may be made read-only by external functions (by omitting a setter)
  • 变量可以通过外部函数变为只读(通过省略setter)
  • A variable may be made write-only by external functions (by omitting a getter)
  • 变量可以由外部函数写入(通过省略getter)
  • Nothing can take a reference to the variable and monkey with it in an uncontrolled manner.
  • 没有什么可以以不受控制的方式引用变量和猴子。
  • In debug all accesses to the variable can be trapped by break-points in the access functions.
  • 在调试中,对变量的所有访问都可以被访问函数中的断点捕获。

Further reading A Pox on Globals (related to embedded systems, but no less applicable generally.

进一步阅读Globals上的A Pox(与嵌入式系统有关,但一般情况下也不例外)。

#3


0  

To share a global variable between two files you should be aware that the variable belongs to the source file which has it declared without "extern". As such, it should also be initialized in that source file. Using extern tells your compiler it will find the variable from some other object file at link time.

要在两个文件之间共享一个全局变量,您应该知道该变量属于没有“extern”声明的源文件。因此,它也应该在该源文件中初始化。使用extern告诉编译器它会在链接时从其他一些目标文件中找到该变量。

As Joachim wrote you also have a problem with your array using this global variable.

正如Joachim所写,使用此全局变量时,您的数组也存在问题。