Next: Libgcc, Previous: Portability, Up: Top
通常情况下GCC被配置为使用与目标系统上相同的函数调用约定。这是通过机器描述宏来实现的(参见Target Macros)。
但是,结构体和联合体的值的返回在一些目标机上采用了不同的方式。于是,使用PCC编译的返回这些类型的函数就不能够被使用GCC编译的代码调用,反之亦然。但是,这并没有造成麻烦,因为很少有Unix库函数是返回结构体或联合体的。
GCC代码使用存放 int
或者 double
返回值的寄存器来返回1,2,4或者8个字节长的结构体和联合体。(GCC还通常将这样类型的变量分配在寄存器中。)其它大小的结构体和联合体在返回时,将它们存放在调用者传给的一个地址中(通常在一个寄存器中)。目标钩子(target hook)TARGET_STRUCT_VALUE_RTX
告诉GCC从哪里来传递该地址。
相比之下,PCC在大多目标机上返回任何大小的结构体和联合体时,都是通过将数据复制到一个静态存储区域,然后将那个存储地址当作指针值返回。调用者必须将数据从那个内存区域复制到需要的地方。这比GCC使用的方法要慢,而且无法重入(reentrant)。
在一些目标机上,例如RISC机器和80386,标准的系统约定是将返回值的地址传给子程序。在这些机器上,当使用这种方法时,GCC被配置为与标准编译器兼容。这可能会对于1,2,4或者8字节的结构体不兼容。
GCC使用系统的标准约定来传递参数。在一些机器上,是前几个参数通过寄存器传递;在另一些机器上,是所有的都通过栈传递。本来是可以在所有机器上都使用寄存器来传递参数的,而且这样还有可能显著提高性能。但是,这样就会与使用标准约定的代码完全不兼容了。所以这种改变只有在你将GCC作为系统的唯一C编译器时才实用。当我们拥有一套完整的GNU系统,能够用GCC来编译库时,我们可以在特定机器上实现寄存器参数传递。
在一些机器上(特别是SPARC),一些类型参数通过“隐匿引用”(invisible reference)来传递。这意味着值是存储在内存中,将内存地址传给子程序。
如果使用 longjmp
,则需要注意自动变量。ISO C规定了没有声明为volatile
的自动变量在 longjmp
之后其值未定义。这也是GCC所承诺的,因为很难正确的恢复寄存器变量的值,而且GCC的一个特点是可以在未作要求的情况下也可以将变量放在寄存器中。