【问题标题】:In C, what does "public" mean when put before a global variable?在 C 中,将“public”放在全局变量之前是什么意思?
【发布时间】:2009-08-09 11:12:51
【问题描述】:

我正在浏览 Mark Nudelman 的“less”unix 工具的源代码,main.c 的开头有很多如下内容:

public int  logfile = -1;
public int  force_logfile = FALSE;
public char *   namelogfile = NULL;

等等。在全局范围内,在 main() 的定义之前,

在这种情况下,公共是什么意思?更重要的是,我自己在哪里可以找到这些信息?我使用无数查询组合进行搜索,但找不到此信息或任何完整的 C 参考。

【问题讨论】:

    标签: c


    【解决方案1】:

    在文件less.h 中是你的答案:

    #define public      /* PUBLIC FUNCTION */
    

    似乎 public 仅用作公共/全局函数和变量的标记。 编译后,它被扩展为空。

    如何找到这些信息?

    1. 在 .c 文件中从顶部搜索到您想要了解更多信息的标识符的位置
    2. 如果没有找到任何声明,请查找 #include 指令
    3. 打开任何包含的文件并查找您要查找的内容的声明
    4. 对每个包含的文件从第二步重复

    在这种情况下,这很简单。

    【讨论】:

    • 不错的发现 :-) 我懒得在某个地方找到源代码并自己寻找 :-)
    • 惊人的发现,谢谢!作为一名程序员,我从中学到的教训是不要用看起来是语言的一部分而不是我的代码的一部分的词来称呼这些东西:)
    • 如果你想在你自己的代码中做这样的事情,只是想在这个问题上添加我的想法......我真的不喜欢这样的#define 试图看起来像关键字源代码,但只是在预处理中消失,因为它会导致读者混淆(这个问题就是证明!)。就我个人而言,我认为所有#define'd 常量/宏都应该是 ALL_UPPER_CASE 以保持清晰/一致。
    • 如果必须将相同的代码构建到 Windows 上的共享库中,并且还可以在 Unix 上运行,那么您必须使用恶作剧来处理 MS declspec 的东西。 GCC 似乎无论如何都可以处理其中的一些(没有详细讨论),但并不是每个编译器都可以。此外,要找到这样的定义,cscope (cscope.sourceforge.net) 等工具可以提供帮助 - 或者更强大的 IDE。
    【解决方案2】:

    这与 C 本身无关。如果您查看包含文件 less.h,您会看到作者定义了许多预处理器指令。其中一些像“public”最有可能是为了可读性。例如:

     /*
     * Language details.
     */
    #if HAVE_VOID
    #define VOID_POINTER    void *
    #else
    #define VOID_POINTER    char *
    #define void  int
    #endif
    #if HAVE_CONST
    #define constant    const
    #else
    #define constant
    #endif
    
    #define public      /* PUBLIC FUNCTION */
    

    查看公共是如何定义的。它被转化为无,正如您已经发现它在全局范围内。然而,它在全局范围内更具可读性和更明显。此外,有人可能会争辩说,如果源代码是这样编写的,并且出现了具有 public 关键字的新版本的 C,则需要重新定义头文件并重新编译以实际使用它.

    这样的预处理技巧甚至可以巧妙地使用,让一个源代码以不同的语言(如 C++ 和 Java)编译。这不是你应该做的事情,但它是可能的。

    您在上面的 less.h 示例中看到的 HAVE_VOID 等选项通常在编译时指定为编译器(实际上是预处理器)选项。因此,如果您有一个编译器和一个支持 void 关键字的 C 版本,您可以使用以下命令编译您的源代码:

    g++ -g -DHAVE_VOID -Wall myprog.C -o 我的程序

    作者在源代码中使用 VOID_POINTER 的任何地方实际上都会被编译器视为:

    void * 
    

    如果您没有指定 HAVE_VOID,编译器将改为使用

    char * 
    

    这是一个合理的替代品。

    提示:检查您的编译器选项,看看您是否可以选择只预处理源代码。这样您就可以查看发送到编译器的实际源代码。

    【讨论】:

    • 是的,我对 gcc -E 很熟悉
    【解决方案3】:

    C 没有关键字“public”,所以它可能是在某个地方的 less 源代码中定义的宏。

    【讨论】:

      【解决方案4】:

      将 public 定义为空的预处理器宏已在其他答案中得到解决。要找到定义,您可能需要使用 ctags/etags 或 cscope 之类的工具。 (有很多工具可以扫描源代码树以生成此信息。)例如,您可以通过调用在 less.h 的第 55 行找到 public 的定义:

      $ ctags -dtw *.c *.h $ vi -t 公开

      或者,在开始编辑之前运行 ctags。当你看到一个你不理解的定义时,将光标放在它上面并输入 ^](这是 control-right 方括号,可以在类似 vi 的编辑器中使用。)

      【讨论】:

      • 请注意,ctags 的选项可能会有所不同。使用 exuberant ctags 不需要任何选项,但某些形式的 ctags 需要 -d 选项来为不带参数的预处理器宏发出标记。 -t 会为 typedefs 发出标签,而 -w 只是为了抑制各种警告。
      猜你喜欢
      • 2011-06-11
      • 2016-10-17
      • 2011-02-16
      • 2021-11-25
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      相关资源
      最近更新 更多