【问题标题】:Declare main prototype声明主原型
【发布时间】:2011-06-28 13:37:34
【问题描述】:

有什么原因我从来没有看到在 C 程序中声明的 main 的原型,即:

int main(int argc, char* argv[]);

int main(int argc, char* argv[])
{
    return 0;
}

似乎总是不一致..

【问题讨论】:

    标签: c standards function-prototypes


    【解决方案1】:

    声明原型意味着你想在别处调用它,这对 main() 函数没有意义。

    【讨论】:

    • 这对 main() 函数没有意义 为什么,标准允许?
    • @jinawee 标准允许和有意义是不同的。为什么需要其他地方的 main 函数声明?
    【解决方案2】:

    不需要原型,因为 main 不应该被其他过程调用(在 C++ 中调用 main 实际上是被禁止的)。

    【讨论】:

    • 据我所知,C99 标准不允许从用户级代码调用main();事实上,第 5.1.2.2.3 节的措辞暗示确实是这种情况:在“初始调用 main 函数”的情况下,人们期望后续调用是可能的......
    • @Christoph:确实我说过它只在 C++ 中是被禁止的;在 C 中,这只是不好的做法。顺便说一句,我想说的是 initial call 并不是将第一次调用与后续调用进行对比,而是说这样的调用发生在执行开始时。
    • 我读到“从初始调用返回等同于exit(),而从后续调用返回只是返回”;但是,您是对的,重复调用main() 在实践中可能会产生不希望的副作用(例如,gcc 将重复调用__main()),这很遗憾,imo:递归调用main() 可能对参数解析很好。 ..
    • @Christoph:我认为您的解释是正确的,当我写该评论时,我没有检查相关段落。 :S
    【解决方案3】:

    C 语言标准,草案n1256

    5.1.2.2.1 程序启动

    1 程序启动时调用的函数名为main实现声明没有 这个函数的原型。它应定义为返回类型int,并且没有 参数:

    int main(void) { /* ... */ }

    或带有两个参数(此处称为argcargv,尽管可以是任何名称 使用,因为它们在声明它们的函数中是本地的):

    int main(int argc, char *argv[]) { /* ... */ }

    或等效;9) 或以其他一些实现定义的方式。

    强调我的。

    【讨论】:

    • 据我所知,这与问题无关:用户级代码不被视为实现的一部分......
    • @Christoph:我和你在一起;没有什么能阻止用户代码为 main 函数声明原型。
    • Re cmets:通过“实现”标准意味着您正在运行的编译器和系统的特定版本。正如它所说的必须或可能由特定编译器/系统“实现定义”的功能一样。例如,声明 main 的选项比给定的两个选项更多。除非有这样的扩展,main 必须按照标准声明。
    • 引用确实无关紧要,它没有回答问题。
    【解决方案4】:

    简单的原因是控件总是首先进入main。因此它由编译器自动定位因此给出它的原型是多余的并且没有用。

    另外,我们在函数定义之前调用函数时会使用原型。因此编译器可以通过查看函数原型来判断调用是否合法。但是在 main 的情况下,我们习惯于提供它的定义和它的声明(这在逻辑上也是正确的)因此不需要原型。

    即使我们将 c 程序组织成多个文件,也不需要 main 的原型

    【讨论】:

      【解决方案5】:

      原型的最初目的是支持对可以由单通道编译器处理的函数的前向引用。

      换句话说,如果你有这样的事情:

      void function_A(){
          printf( "%d", function_B( 5 ) );
      }
      
      int function_B( int x ){
          return x * 2;
      }
      

      function_B 在定义之前被调用。这会给简单的编译器带来问题。为了避免这些问题,将原型放在文件的开头,可以确保编译器提前知道文件中的所有函数,因此前向引用对类型检查来说不是问题。

      由于编译器事先知道 main 函数的所有有效形式,因此没有必要创建原型,因为编译器可以在没有它的情况下对 main() 的前向引用进行类型检查。

      【讨论】:

        猜你喜欢
        • 2011-08-07
        • 2012-07-15
        • 2021-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        相关资源
        最近更新 更多