2016-06-14 91 views
-2

主要问题是:C编译器如何处理不同源代码中main函数的多个定义? 像:C编译器如何处理不同的主函数定义?

无效的主要(无效)

INT主要(无效)

INT主(INT ARGC,CHAR *的argv []) ...

我不知道如果这与名称修饰有关,那只有当C代码与C++代码链接而不使用extern“C”时才会发生,但我只是通过Linux程序员手册(shell上的普通人命令)查询功能打开(man 2打开)并显示两个签名:

OPEN(2)的Linux程序员手册

NAME

open, creat - open and possibly create a file or device 

提要

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 

    int open(const char *pathname, int flags); 
    int open(const char *pathname, int flags, mode_t mode); 

    int creat(const char *pathname, mode_t mode); 

这可怎么工作的?它的处理就像主函数的定义一样?

+1

我想知道你的意思是不同类型的多重声明或多重定义。如果你给出了你的行为不清楚的示例代码(你自己的程序),这将有所帮助。目前还不清楚这个问题与[linux]和[C++]有什么关系。 – PJTraill

+1

名称修饰不会发生在C名称上,而是C++名称超载,以适应链接器的限制。因此,它与C编译器(也可能是链接器)在你的程序中的作用没有任何关系。 – PJTraill

+0

这不是有效的C代码。 C和C++是**不同的**语言!即使相同的语法/语法也可以具有不同的语义。 – Olaf

回答

2

无论如何它喜欢。如果您未以标准禁止的两种方式之一声明main,或者您以两种的方式声明它,则编译器可以将您的汽车传送到月球,如果它想。进一步的合理化是毫无意义的。

[C99: 5.1.2.2.1/1]:[..]它应具有的int返回类型和不带参数进行定义:[..]具有两个参数[..]

[C99: 5.1.2.2.1/2]:如果声明它们,则主函数的参数应服从以下约束条件:[..]

[C99: 3.4.3/1]:未定义行为
行为,在使用非便携式或错误的程序结构的或错误的数据,对于这本国际标准并没有规定要求

4

open实际上并不具有过载或多个声明。它被宣布为open(const char *pathname, int flags, ...),第三个参数被读取为va_arg,并且当flags包括O_CREAT时被解释为mode_t

如果您有多个main的定义或者具有相同C名称的多个符号,那么您可能会遇到链接器错误。

+0

谢谢zneak,很好的回答 – joaopauloribeiro

+0

我想我误解了,关于主要的问题不是关于在同一个源代码中有两个或多个定义,而是编译器如何处理不同代码中的不同定义,就像我可以做的那样void main(void)或int main(void)... – joaopauloribeiro

+1

@joaopauloribeiro,编译器负责确保'main'被C运行时正确调用。它被调用的方式必须考虑到它可能有也可能没有参数,可能会或可能不会返回一个值(在'main'被允许返回'void'作为C标准的扩展的平台上)。它可以被视为一种特殊情况;你不一定会得到这种宽容与其他功能。 – zneak

3

C编程语言的典型实现可以容忍调用者将太多参数传递给函数。在类Unix系统中,当启动代码调用到main,它通过三个参数,就好像main被宣布为

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

,其中第三个参数是环境。如果main定义的参数少于这个参数,那么与典型的调用约定一样,所有东西仍然可以正常工作,额外的参数放置方式不会受到影响(例如,在第一个参数之上的堆栈或额外的寄存器中) 。

历史上,open函数的工作原理类似:open被声明为没有原型,所以编译器无法检查您传递了多少个参数。 open的定义期望三个参数,如果你只传递了两个参数,open将为第三个参数获取堆栈上的所有内容,这并不重要,因为当调用open而不是O_CREAT时,第三个参数不会影响结果。

+0

因此,如果打开的函数抓取堆栈中的“whatever”,它可能会打破其他函数的堆栈? – joaopauloribeiro

+1

与生活中的一切 - 你可以抓住少于你的份额,但尝试采取更多,并承受后果。 – SergeyA

+1

@joaopauloribeiro由于它不会覆盖它的参数,并且'open'永远不会是顶层栈帧,所以这不是问题。 – fuz