【问题标题】:Can the C main() function be static?C main() 函数可以是静态的吗?
【发布时间】:2009-05-29 08:02:38
【问题描述】:

main() 函数可以在 C 程序中声明为static 吗?如果是,那它有什么用呢?

我是否可以使用汇编代码并自己调用static main() 函数(考虑嵌入式程序)?

【问题讨论】:

    标签: c static linker


    【解决方案1】:

    没有。 C 规范实际上在其中的某处说(我读过规范,信不信由你)主函数不能是静态的。

    原因是静态的意思是“不要让这个源文件之外的任何东西使用这个对象”。好处是当你去链接时它可以防止 C 中的名称冲突(如果你在不同的文件中有两个名为“is_initialized”的全局变量,那就太糟糕了……除非你做了它们,否则它们会被静默合并静止的)。它还允许编译器执行某些其他方式无法执行的优化。这两个原因就是为什么拥有静态是一件好事。

    由于您无法从文件外部访问静态函数,操作系统如何访问 main 函数来启动您的程序?这就是为什么 main 不能是静态的。

    一些编译器特别对待“main”,当你将它声明为静态时可能会默默地忽略你。

    编辑:看起来我错了,规范说 main 不能是静态的,但它确实说它不能在托管环境中内联(如果您必须询问“托管环境”是什么意思,那么你在一个)。但是在 OS X 和 Linux 上,如果你声明 main static,那么你会得到一个链接错误,因为链接器找不到“main”的定义。

    【讨论】:

    • 理论上您可以使用 -ffreestanding 来避免链接 crt0.o(或 crt1.o 或 crti.o 或任何 GCC 在您的平台上使用的),编写您自己的 _start 引用 main 和然后使主要静态。这与“如果你不得不问“托管环境”是什么意思,那么你就在一个中'虽然:)
    • +1 非常好的回应,我只是想澄清根本原因,即存根链接在一起,依赖于某些外部可见符号的事实
    • 我认为标准只要求你有一个外部main 函数。它是否真的禁止在其他翻译单元中使用静态链接main
    【解决方案2】:

    你可以在源文件中有一个名为 main() 静态函数,它可能会编译,但它不会是 main() 函数,因为它当启动代码(许多(旧)Unix 系统上的 crt0.o)调用 main() 时,链接器将不可见。

    给定代码:

    static int main(int argc, char **argv)
    {
        return(argv + argc);
    }
    
    extern int x(int argc, char **argv)
    {
        return(main(argc, argv));
    }
    

    带有 -Wall 的 GCC 很有帮助地说:

     warning: 'main' is normally a non-static function
    

    是的,可以做到。不,这通常是一个错误 - 它不是 main() 函数。

    【讨论】:

    • 但我想知道这是如何被允许的并且也应该起作用。 main() 是程序启动时需要调用的函数。一个程序中怎么会有两个main()?即使你在一个源文件中有一个main() 并且它只在那里使用。链接器在哪里知道哪个main() 是程序启动时要调用的“主”(假设两者都没有冲突的原型)?
    • @RobertSsupportsMonicaCellio:只要其中至少一个是static,就可以在不同的翻译单元(目标文件)中拥有两个同名的函数——例如widget_picker()。相同的规则适用于名称main()。不同之处在于链接器查找非静态main()(它不关心称为main()static 函数;它们在定义它们的TU 之外不可见)并确保执行开始在可执行文件中的(仅)非静态main()
    【解决方案3】:

    不,你不能这样做。如果你这样做,你将无法编译你的程序。因为静态函数只在同一个文件中可见,所以链接器将无法找到并调用它。

    【讨论】:

      【解决方案4】:

      正如其他人所说,不,它不能。如果您打算将代码移植到 C++ 中,那会加倍,因为 C++ 标准规定 main() 实际上不必是函数。

      【讨论】:

      • 我认为这不准确。 ISO/IEC 14882:2011 第 3.6.1 节主函数说:程序应包含一个名为 main 的全局函数,它是程序的指定开始。
      【解决方案5】:

      C对于'static'有两种含义...

      局部变量的静态意味着它可以在全局范围内使用。 static 对于全局变量意味着只能在当前文件中使用。

      函数的静态与将全局变量表示为静态具有完全相同的影响...静态函数仅在当前文件中可见...

      因此 main 永远不能是静态的,因为它不能作为程序的主要入口点。

      【讨论】:

      • 你说“局部变量的静态意味着它可以全局使用”。你是什​​么意思?将static 应用于局部变量(即在函数中使用static 定义的变量)似乎不是有效的解释。
      猜你喜欢
      • 2020-12-26
      • 1970-01-01
      • 2013-05-28
      • 2011-01-16
      • 2021-10-18
      • 2017-09-30
      • 2011-12-22
      • 2013-06-24
      • 1970-01-01
      相关资源
      最近更新 更多