代码之家  ›  专栏  ›  技术社区  ›  kagali-san

如何定义和声明供库代码使用的全局变量?

c
  •  1
  • kagali-san  · 技术社区  · 15 年前

    主文件(prog.c):

    #include "log.c"
    #include "library.c"
    static char * Foo;
    

    如果在主文件(prog.c)中定义了某个变量(char*foo),并且该变量是从library.c调用的log.c函数所必需的,那么如何正确地声明foo在log.c的命名空间中可见?

    4 回复  |  直到 15 年前
        1
  •  2
  •   Jonathan Leffler    15 年前

    通常在主程序中包含库源代码:

    #include "log.c"
    #include "library.c"
    static char * Foo;
    

    (需要半结肠。)

    但是,考虑到这就是您要做的,如果“log.c”需要查看声明,您可以简单地执行以下操作:

    static char * Foo;
    #include "log.c"
    #include "library.c"
    

    现在静态声明对“log.c”(和“library.c”)可见。

    如果您使用更传统的设置,那么“log.c”中的代码将访问在适当头文件(而不是文件静态变量)中声明的全局变量。然而,这种依赖性(库文件依赖于全局变量)是一种麻烦。主程序(或某些代码)必须提供变量定义。最好让“log.c”中的代码定义变量,并且(假定的)头“log.h”将声明变量,然后主程序将相应地设置变量。或者,更好的是,“log.c”中的代码将提供一个或多个函数来操作变量,并且头将声明这些函数,主程序将使用它们。

        2
  •  2
  •   RBerteig Keith Adler    15 年前

    将其声明添加到两个.c文件中都包含的一些.h文件中。在其中一个文件中定义它。

    当然,不能申报 static 为了这个工作自 静止的 关键字是一种承诺,即在该特定模块之外不需要该名称。

    例如,在 prog.h :

    extern char *Foo;
    

    在里面 prog.c :

    #include "prog.h"
    #include "log.c"
    #include "library.c"
    
    char * Foo;         // make sure that Foo has a definition
    
    // some code probably wants to make Foo have a value other than NULL
    

    在里面 log.c :

    //... other includes
    #include "prog.h"    // and now Foo is a known name
    
    // some code here is using the global variable Foo
    

    现在,为了坏消息。

    这样做会在 丙丙 log C 模块。这种耦合增加了整个应用程序的维护成本。一个原因是没有办法阻止其他模块也使用全局变量。更糟糕的是,他们可能是偶然地完全使用了它,因为它的名称没有足够的描述性。

    更糟糕的是,全局性使得从单线程程序转移到多线程程序变得更加困难。可能从多个线程访问的每个全局变量都是很难诊断错误的潜在来源。解决方法是保护同步对象必须是全局的信息,但使用过度会导致应用程序中除当前使用全局线程外的所有线程都被阻塞,从而使多线程应用程序有效地单线程。

    当然,有时全局变量所暗示的模块间耦合是可以接受的。一个用例用于通用的应用程序范围选项。例如,如果应用程序支持 --verbose 使其工作时发出颤音的选项,那么由选项设置并在整个代码中测试的标志将是全局变量,这是有意义的。

    当然也存在一些问题,以便深入研究全球的陷阱,并为它们的合理使用提供指导。

        3
  •  1
  •   Paul Rubel    15 年前

    你想要外部的。当你输出一个变量名时,你会做出一个“承诺”,即当你链接时变量会存在。您希望将其存储在.c文件中,但在头文件中将其删除。这样,它就在.c的对象文件中实例化了一次。您不希望有两个不同的名称。o使用相同的名称来引用内存中的不同位置。(如上所述,图书馆需要这样的东西几乎总是不好的形式。)

    所以在一个共同的标题里你会

    普通H

    extern Foo bar;
    

    然后在丙

    起泡棒;

    当您在log.c中包含common.h时,可以从prog.c访问bar。

    注意,C中的静态与Java非常不同。在Java中,它是全局的,并且对于任何人都可用,即使没有该类的实例。在C static中,表示变量在编译单元之外不可见。

        4
  •  1
  •   Clifford    15 年前

    简单的答案是:

    static char * Foo;
    #include "log.c"
    #include "library.c"
    

    这使得 Foo 在log.c和library.c中只通过“使用前声明”规则可见。

    但是你真正需要知道的是 肮脏的 代码!你已经承诺了至少两个 罪恶 ; Use of global variables 不了解使用方法 separate compilation and linking .