Oracle® Developer Studio 12.5:C 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

2.18 在独立式环境中编译

Oracle Developer Studio C 编译器支持编译与标准 C 库链接、并在包含标准 C 库和其他运行时支持库的运行时环境中执行的程序。C 标准将此类环境称为托管环境。而将未提供标准库函数的环境称为独立式环境。

针对于独立式环境,一般情况下 C 编译器不支持编译,因为某些可能从编译代码中调用的运行时支持函数一般仅在标准 C 库中可用。问题是:编译器转换源代码时可能会导致在不包含函数调用的源代码结构中调用运行时支持函数,而这些函数一般在独立式环境中不可用。请看以下示例:

% cat -n lldiv.c
	 1	void
	 2	lldiv(
	 3	    long long *x,
	 4	    long long *y,
	 5	    long long *z)
	 6	{
	 7	    *z = *x / *y ;
	 8	}
% cc -c -m32 lldiv.c
% nm lldiv.o | grep " U "
 0x00000000 U __div64
% cc -c -m64 lldiv.c
% nm lldiv.o | grep " U "

在该示例中,使用 -m32 选项编译源文件 lldiv.c 使其在 32 位平台上运行时,对第 7 行中声明的转换将导致外部引用名为 __div64 的运行时支持函数,并且此函数是 32 位版本的标准 C 库中唯一可使用的函数。

使用 -m64 选项编译同一源文件使其在 64 位平台上运行,编译器将使用目标计算机中的 64 位算法指令集,但其中不包括 64 位版本的标准 C 库中运行时支持函数所需要的指令。

尽管在一般情况下不支持使用 C 编译器将独立式环境视为目标,但在遵从注意事项的情况下可使用此编译器在特定的独立式环境(即 Oracle Solaris 内核和设备驱动程序)中编译代码。

必须写入在 Oracle Solaris 内核中运行的代码(包括设备驱动程序),这样外部函数调用才能引用那些只在内核中可用的函数。要使以上情况成为可能,建议遵从以下准则:

  • 对于只在用户模式下运行的库,不要包含头文件。

  • 除非确定内核中存在与标准 C 库或其他用户模式库中相同的函数,否则不要调用这些函数。

  • 不要使用浮点类型或复合类型。

  • 不要使用与运行时支持库相关联的编译器选项(例如 -xprofile-xopenmp-xautopar)。

    cc(1) 手册页的“文件”一节中介绍了与特定编译器选项关联的可重定位对象文件。相关选项的说明下面介绍了与 C 编译器选项关联的运行时支持库。

如前所述,在源代码转换后,编译器可能会生成对运行时支持函数的调用。对于 Oracle Solaris 内核,在特定情况下可能被调用的运行时支持函数集要小于一般情况下调用的相应函数集,因为内核不使用浮点/复合类型、数学库函数或与运行时支持库相关联的编译器选项。

下表列出了 C 编译器转换源代码后,可能被调入代码中的运行时支持函数,这些代码是为了能够在 Oracle Solaris 内核中运行而编译的。此表列出了其上的源代码转换生成了调用的平台、被调用函数的名称,以及导致生成函数调用的原结构或编译器功能。仅列出了 64 位平台,因为支持 C 编译器的所有版本的 Oracle Solaris 均在 64 位内核中运行。

针对于 32 位指令集进行编译时,可能会因指令集的特定限制而调用特定于其他计算机的支持函数。

表 5  运行时支持函数
函数
64 位平台
引用自
__align_cpy_n
SPARC
返回大structn 取值为 1、2、4、8 或 16
_memcpy
x86
返回大 struct
_memcpy
x86 和 SPARC
矢量化
_memmove
x86 和 SPARC
矢量化
_memset
x86 和 SPARC
矢量化

注意:一些内核的版本不提供 _memmove()_memcpy()_memset(),但提供与用户模式例程相似的内核模式例程 memmove()memcpy()memset()

务必注意,针对 x86 平台编译 Oracle Solaris 内核代码时,必须使用选项 –xvector=%none。缺省情况下,C 编译器在 x86 平台上使用 XMM 寄存器生成代码以改善常规用户应用程序的性能,包括不使用 C 浮点运算类型的应用程序。使用 XMM 寄存器不适用于内核代码。

可在《编写设备驱动程序指南》和《SPARC 遵从性定义》(版本 2.4)中找到其他信息。