【问题标题】:Two main functions两个主要功能
【发布时间】:2011-02-07 06:22:06
【问题描述】:

我们可以在 C++ 程序中有两个 main() 函数吗?

【问题讨论】:

  • 我猜面试题不好
  • lexflexlibl.alibfl.a 中提供自己的main(以及yywrap),因此您可以编写词法分析器而无需编写自己的@ 987654328@。他们的内容来自stdin。如果您想要自己的(几乎总是),只需编写您自己的。

标签: c++ main


【解决方案1】:

在一个程序中,只允许一个入口点。

【讨论】:

    【解决方案2】:

    在任何命名空间之外只能将一个函数命名为main,就像任何其他名称一样。如果你有命名空间foobar (等等),你完全可以拥有名为foo::mainbar::main 等的函数,但从系统的角度来看,它们不会被视为任何特殊的东西(只有在任何命名空间之外名为main 的函数才会被特殊处理,作为程序的入口点)。当然,从您的main 中,您完全可以调用各种foo::mainbar::main 等等。

    【讨论】:

    • 其实通常可以有多个函数同名,只要参数不同...
    • @James:是的,我更多地指的是“就像任何其他名称一样”。全局函数main 是个例外,这就是为什么我说函数通常 可以被重载。对于所有 (?) 其他函数,可以有多个具有相同名称的重载。
    【解决方案3】:

    您不能在全局范围内重载 main()。

    【讨论】:

      【解决方案4】:

      是的!为什么不呢?

      考虑以下代码:

       namespace ps
       {
           int main(){return 0;}
       }
      
       int main()
       {
           ps::main();
       }
      

      它的::main()将在执行期间被调用。

      【讨论】:

        【解决方案5】:

        一个程序只能有一个入口点,但当然,一个 main() 函数可以调用其他函数,具体取决于您要指定的任何逻辑。因此,如果您正在寻找一种将两个或多个程序有效地编译为单个可执行文件的方法,您可以执行以下操作:

        int main(int argc, char ** argv)
        {
           if (argc > 0)  // paranoia
           {
                   if (strstr(argv[0], "frogger")) return frogger_main(argc, argv);
              else if (strstr(argv[0], "pacman"))  return pacman_main(argc, argv);
              else if (strstr(argv[0], "tempest")) return tempest_main(argc, argv);
           }
        
           printf("Hmm, I'm not sure what I should run.\n");
           return 10;
        }
        

        ...然后只需将您的“其他”main() 函数重命名为 frogger_main()、pacman_main() 或您愿意为其命名的任何名称,如果可执行文件名称为 Frogger,您将拥有一个作为 Frogger 运行的程序包含“frogger”一词,或者如果可执行文件中包含名称“pacman”,则以 PacMan 运行,等等。

        【讨论】:

          【解决方案6】:

          哦,诡计问题!

          简短回答:“视情况而定。”

          长答案:正如其他人指出的那样,您可以拥有多个名为 main 的函数,只要它们位于不同的命名空间中,并且仅使用根命名空间中的 main(即 ::main)作为主程序。事实上,一些线程库的线程类有一个名为 main 的方法,库用户用他们希望在线程中运行的代码覆盖该方法。

          现在,假设您没有使用任何命名空间技巧,如果您尝试在两个不同的 .cpp 文件中定义 ::main,则文件本身都会编译,但是,链接器将中止,因为有两个名为main;它不知道要链接哪个。

          (我有一个问题请教大师:在 C++ 中,函数定义 int main() {}extern "C" int main() {} 是否生成具有相同签名的函数?我自己没有尝试过。)

          现在您的程序源代码中可以有多个::main:如果一个main 在库(.a 或 .so 文件)中,另一个在在您的源 (.o) 文件中,您的源中的那个获胜,而库中的那个被删除,并且链接成功,除非还有其他问题!如果您没有main,图书馆的main 会赢。这实际上是在 lexyacc 附带的支持库中完成的;他们提供了一个准系统main,因此您不必为快速解析器编写一个。

          这导致了一个有趣的应用程序:为每个库提供一个main。我的库往往很小而且很集中,所以我在每个库中都放了一个main.cpp 和一个main,它是库的测试或实用程序代码。例如,我的共享内存库有一个main,它允许从命令行调用管理共享内存的所有函数。然后我可以用bash 脚本测试各种情况。任何链接到共享内存库的东西都可以免费获得测试代码,或者可以通过定义自己的main 来处理它。

          编辑:为了确保人们清楚这个概念,我正在谈论一个看起来像这样的构建:

          gcc -c -o bar_main.o bar_main.cpp
          ar -r libbar.a bar_main.o
          ranlib libbar.a
          gcc -c -o foo_main.o foo_main.cpp
          gcc -o foo foo_main.o -L. -lbar
          

          在此示例中,foo_main.o 中的 main 优于 bar_main.o 中的 main。该标准没有定义这种行为,因为他们不在乎。无论如何,人们都会使用很多非标准的东西。 Linux 就是一个使用 C 位域的例子。 ld 以这种方式工作的时间比我知道如何打字的时间长。

          说真的,伙计们,如果您需要生成最小公分母代码,请随意严格遵守标准。但是,如果您有幸在可以构建lexyacc 程序的平台上工作,那么一定要考虑利用它。

          【讨论】:

          • 未定义的行为可以包括您观察到的行为。这并不意味着“您可以拥有多个”和“源中的那个获胜”,它只是意味着您的实现为您选择了该行为。对你来说太糟糕了,等到你的客户得到不太满意的结果。
          • 这仅在第一个 main 被声明为弱符号时才有效。如果您有弱符号和常规符号,则常规符号获胜,弱符号被丢弃。如果您有两个弱符号,其中一个会以某种方式获胜。如果你有两个正则符号,那就是错误。
          • @Windows:自从 gcc 2.7.2.2 以来,我们已经这样做了 12 年,没有出现任何问题。但是,我们以 Linux 为目标,所以也许它是 Windows 与其他所有东西的对比。 @Adam:那么听起来我们的库符号默认是弱的,假设你在谈论 Unix。
          • 未定义的行为是未定义的行为。哪个操作系统与哪个对抗并不重要,重要的是哪个语言标准与 Mike DeSimone 对抗。
          • 实际上,我的印象是,只有当编译器说它很重要时,它才重要。所以我可以随意做这件事,直到我做不到为止。 “未定义”并不意味着“不要这样做”或“这会破坏”;它只是意味着“这个标准不是相关的权威;找到另一个”。
          【解决方案7】:

          标准在 3.6.1 中明确规定:

          程序应包含一个名为 main 的全局函数,它是程序的指定开始。 [...] 这个函数不能被重载。

          所以在一个程序的全局范围内只能有一个main函数。其他范围内也称为main 的函数不受此影响,可以有任意数量。

          【讨论】:

            【解决方案8】:

            在全局范围内只有一个入口点。

            【讨论】:

              猜你喜欢
              • 2012-07-18
              • 2011-06-18
              • 1970-01-01
              • 1970-01-01
              • 2020-08-12
              • 2015-01-24
              • 1970-01-01
              • 1970-01-01
              • 2015-04-27
              相关资源
              最近更新 更多