关于标准中的程序启动

时间:2014-09-29 01:25:45

标签: c language-lawyer

我对标准中的第5.1.2.2.2节有几个问题。

  
      
  1. 程序启动时调用的函数名为 main 。该实现声明此函数没有原型。应该是   使用返回类型 int 定义并且没有参数:

         

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

         

    或带有两个参数(此处称为    argc argv ,虽然可以使用任何名称,因为它们是本地的   声明它们的函数:

         

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

         

    或同等的; 10)或其他一些   实施定义的方式。

  2.   

“其他一些实现定义的方式”是指什么?是否提到脚注10,其中指出:

  

因此, int 可以替换为定义为 int 的typedef名称,或者    argv 的类型可以写成 char ** argv ,依此类推。

...还是主要的实际定义?如果是这样,这是否意味着给定某个实现,编译器可以说main应该被定义但是它想要(这与我在互联网上读到的说法必须是int main相反。例如,在第5.1.2.2.3节中,它声明:

  
      
  1. 如果功能的返回类型是与 int 兼容的类型,则从初始调用函数返回的是当量   使用 main 返回的值调用退出函数   作为其参数; 11)到达终止 main }   函数返回值0.如果返回类型不兼容   使用 int ,返回到主机环境的终止状态是   未指定的。
  2.   

......这似乎为实施留下了很大的余地。

  

- 参数 argc argv 以及指向的字符串    argv 数组应由程序修改,并保留   它们在程序启动和程序之间的最后存储值   终止。

“保留最后存储的值意味着什么”?这是否意味着像getopt这样的函数违反了标准,因为它们会置换argv?

2 个答案:

答案 0 :(得分:2)

  

"其他一些实现定义的方式"参考?

C标准仅为main提供了两个签名:

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

但是一些实现还允许一些不同的签名。

在Mac OS上:

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

在Windows上:

int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);  

POSIX支持

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

答案 1 :(得分:1)

没有;这意味着Microsoft可以记录:

void main(int argc, char **argv, char **envp)

作为main()在其系统上的有效签名,并且由于'或其他一些实现定义的方式'而有效。

脚注表示您可以使用:

typedef int num;

num main(num argc, char **argv)

它仍然有效。

另见What should main() return in C and C++

“上次修改后的值”位表示当getopt()置换argv中的值时,它设置的排列将一直有效,直到被其他更改argv中的值的内容覆盖。