【问题标题】:How to make this code compile?如何使这段代码编译?
【发布时间】:2010-03-25 20:52:02
【问题描述】:

// 文件:foo.c

static int var;

void foo()
{
var++;
}

// foo.c 文件结束

// 文件 bar.c:

static int var;

void bar()
{
var++;
}

// 文件 bar.c 结束

// 文件 main.c

static int var;
void main()
{
foo();
bar();
printf("%d", var);
}

// 文件 main.c 结束

问题:上面的程序可以编译吗?如果是这样,结果会怎样?

我测试了代码,发现它无法编译。我尝试在 main.c 中使用 extern 来使用函数 foo() 和 bar() 但仍然无法编译。

【问题讨论】:

  • @nvl:应该为零。正确分隔文件。
  • 您需要发布 (a) 用于尝试构建它的命令以及 (b) 从编译器和/或链接器获得的错误消息
  • @Isak:为什么这对这种情况很重要。没有人为 OP 编写代码。我认为帮助人们开始编译他们的代码是完全可以的。否则,他们还能如何尝试编写自己的程序?
  • @nvl:因为var 是静态的,因此应该是每个文件的本地文件。因此,main.c 中的var 应该与foobar 保持一致,因为它们都有自己的var 变量。这也是我从 GCC 4.2.1 得到的行为。
  • @nvl:为什么在地球上你想这样做?

标签: c


【解决方案1】:

main.c 有一些小问题 - 它应该是这样的:

#include <stdio.h>

static int var;

extern void foo();
extern void bar();

int main(void)
{
    foo();
    bar();
    printf("%d\n", var);
    return 0;
}

它应该像这样构建好的:

$ gcc -Wall main.c foo.c bar.c -o main

结果应该是:

$ ./main
0

【讨论】:

  • GCC 实际上使用main.c 编译它,如问题中所述。它只是在 printfmain 返回类型上抛出关于隐式声明的警告。
  • 为什么函数原型需要extern
  • @jleeddev: extern 在这种情况下并不是绝对必要的,但有些人认为它是一种很好的风格
  • @skydoor - 是的,如果你省略 extern,它就会隐含在函数原型中,就像 int 在某些情况下可以隐含一样。
【解决方案2】:

我希望它能够编译并打印 0(但如果您想将其编译为 C++,则必须添加 foo()bar() 的声明,在 C 或 C++ 中,您可能会得到一个警告main() 应该真正返回一个 int)。

由于var 在三个文件中的每一个中都被定义为静态,因此您确实拥有三个独立的变量,它们恰好都具有相同的名称。也许最容易将每个文件视为定义一个包含其静态变量的结构。你所做的称为foo(),它递增foo.var。然后你调用了bar(),它增加了bar.var。然后你打印出main.var,它被初始化为零,从未被修改过。

【讨论】:

    【解决方案3】:

    这是为我编译的(尽管带有关于来自main() 的返回类型的警告)。

    结果,就main() 将打印的内容而言,是不确定的,因为您尚未在main.c 中初始化var 的值。当编译器在没有优化的情况下被调用时,最可能的结果是零,因为操作系统会将提供给进程用于数据存储的物理内存归零(操作系统这样做是为了避免在进程之间泄漏机密数据)。

    var 变量定义的静态限定符意味着该变量在定义它的源文件之外不可见。这也意味着三个var 变量中的每一个都有自己的存储位置。

    如果我们将printf("[module name] *var=%p\n", &amp;var) 分别添加到foo()bar()main() 以打印存储这三个变量的内存位置的地址,您应该得到如下结果:-

    foo() *var=0x8049620
    bar() *var=0x8049624
    main() *var=0x8049628
    

    请注意,每个变量都有自己的存储位置。每个源文件中的代码将访问特定于该源文件的 var 版本。在 .c 文件中像这样使用static 通常用于实现 C 中信息隐藏的概念。

    【讨论】:

      【解决方案4】:

      代码(原样)将编译,结果将为 0(正如 Jerry 解释的那样),因为 static 变量将具有文件范围。

      但是,如果您在main.c 中包含foo.cbar.c,并编译为

      gcc main.c
      

      那么结果将是2,因为只有一个全局变量var

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-31
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        相关资源
        最近更新 更多