JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:C 用户指南     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  C 编译器介绍

2.  特定于 C 编译器实现的信息

3.  并行化 C 代码

4.  lint 源代码检验器

5.  基于类型的别名分析

6.  转换为 ISO C

7.  转换应用程序以适用于 64 位环境

7.1 数据模型差异概述

7.2 实现单一源代码

7.2.1 派生类型

7.2.1.1 <sys/types.h>

7.2.1.2 <inttypes.h>

定宽整型

诸如 unintptr_t 的有用类型

常量宏

限制

格式字符串宏

7.2.2 使用 lint 检查

7.3 转换为 LP64 数据类型模型

7.3.1 整型和指针长度更改

7.3.2 整型和长型长度更改

7.3.3 符号扩展

7.3.4 指针运算而不是整数

7.3.5 结构

7.3.6 联合

7.3.7 类型常量

7.3.8 注意隐式声明

7.3.9 sizeof( ) 是无符号 long

7.3.10 使用强制类型转换显示您的意图

7.3.11 检查格式字符串转换操作

7.4 其他转换注意事项

7.4.1 注意:长度增长的派生类型

7.4.2 检查更改的副作用

7.4.3 检查直接使用 long 是否仍有意义

7.4.4 对显式 32 位与 64 位原型使用 #ifdef

7.4.5 调用转换更改

7.4.6 算法更改

7.5 入门指导核对表

8.  cscope:交互检查 C 程序

A.  按功能分组的编译器选项

B.  C 编译器选项参考

C.  实现定义的 ISO/IEC C99 行为

D.  C99 的功能

E.  实现定义的 ISO/IEC C90 行为

F.  ISO C 数据表示法

G.  性能调节

H.  Oracle Solaris Studio C:K&R C 与 ISO C 之间的差异

索引

7.2 实现单一源代码

以下各节介绍可用于编写支持 32 位和 64 位编译的单一源代码的一些可用资源。

7.2.1 派生类型

使用系统派生类型使代码对于 32 位和 64 位编译环境均安全,这是一种好的编程做法。使用派生数据类型时,只有系统派生类型由于数据模型更改或移植而需要更改。

系统 include 文件 <sys/types.h><inttypes.h> 包含有助于使应用程序对于 32 位和 64 位编译环境均安全的常量、宏和派生类型。

7.2.1.1 <sys/types.h>

在应用程序源文件中包含 <sys/types.h> 以访问 _LP64_ILP32 的定义。此头文件还包含适当时应使用的多个基本派生类型。尤其是以下类型更为重要:

所有这些类型在 ILP32 编译环境中保持为 32 位值,并会在 LP64 编译环境中增长为 64 位值。

7.2.1.2 <inttypes.h>

include 文件 <inttypes.h> 提供有助于使代码与显式指定大小的数据项兼容(无论编译环境如何)的常量、宏和派生类型。它包含用于处理 8 位、16 位、32 位和 64 位对象的机制。<inttypes.h> 提供的基本功能包括:

以下各节提供有关 <inttypes.h> 基本功能的更多信息。

定宽整型

<inttypes.h> 提供的定宽整型包括带符号整型(如 int8_tint16_tint32_tint64_t)和无符号整型(如 uint8_tuint16_tuint32_tuint64_t)。

定义为可容纳规定位数的最短整型的派生类型包括 int_least8_tint_least64_tuint_least8_tuint_least64_t 等。

对于循环计数器和文件描述符等操作,使用 intunsigned int 是安全的。对于数组索引,使用 long 也是安全的。但是,不应不加选择地使用这些定宽类型。可将定宽类型用于下列各项的显式二进制表示:

诸如 unintptr_t 的有用类型

<inttypes.h> 文件包括大小足以容纳一个指针的带符号整型和无符号整型。这些类型以 intptr_tuintptr_t 形式提供。此外,<inttypes.h> 还提供 intmax_tuintmax_t,后两者是可用的最长(以位为单位)带符号整型和无符号整型。

使用 uintptr_t 类型作为指针的整型而非基本类型,如 unsigned long。尽管在 ILP32 和 LP64 数据模型中,unsigned long 与指针的长度相同,但如果使用 uintptr_t,则在数据模型更改时,只有 uintptr_t 的定义受影响。通过此方法可以将代码移植到许多其他系统,也是一种在 C 中表达意图更清晰的方法。

需要执行地址运算时,intptr_tuintptr_t 类型对于强制转换指针非常有用。因此,应使用 intptr_tuintptr_t 类型,而不是 long 或无符号 long

常量宏

使用宏 INT8_C(c)INT64_C(c)UINT8_C(c)UINT64_C(c) 等指定给定常量的大小和符号。基本上,必要时这些宏会在常量的末尾添上 lulllull。例如,对于 ILP32,INT64_C(1) 会在常量 1 后面附加 ll;对于 LP64,则附加 l。

可使用 INTMAX_C(c)UINTMAX_C(c) 宏使常量成为最长类型。这些宏对于指定7.3 转换为 LP64 数据类型模型中介绍的常量类型会非常有用。

限制

<inttypes.h> 定义的限制是用于指定各种整型的最小值和最大值的常量,这些限制包括每个定宽类型的最小值(如 INT8_MININT64_MIN 等)和最大值(如 INT8_MAXINT64_MAX 等)及其对应的无符号的最小值和最大值。

<inttypes.h> 文件还提供每个最短长度类型的最小值和最大值,这些类型包括 INT_LEAST8_MININT_LEAST64_MININT_LEAST8_MAXINT_LEAST64_MAX 等及其对应的无符号的最小值和最大值。

最后,<inttypes.h> 还定义支持的最长整型的最小值和最大值,这些类型包括 INTMAX_MININTMAX_MAX 及其对应的无符号的最小值和最大值。

格式字符串宏

<inttypes.h> 文件包括指定 printf(3S)scanf(3S) 格式说明符的宏。实质上,如果宏名称内置了参数的位数,这些宏将在格式说明符前面添加 lll,以便将参数标识为 longlong long

printf(3S) 的某些宏以十进制、八进制、无符号和十六进制格式输出最短和最长整型,如下例所示。

int64_t i;
printf("i =%" PRIx64 "\n", i);

同样,scanf(3S) 的宏以十进制、八进制、无符号和十六进制格式读取最短和最长整型。

uint64_t u;
scanf("%" SCNu64 "\n", &u);

不要不加区别地使用这些宏。最好将它们与定宽整型中介绍的定宽类型一起使用。

7.2.2 使用 lint 检查

lint 程序的 -errchk 选项检测潜在的 64 位端口问题。也可以指定 cc -v,该选项指示编译器执行更严格的附加语义检查。-v 选项还会针对指定文件启用某些类似 lint 的检查。

将代码增强到 64 位安全时,应使用 Oracle Solaris 操作系统中出现的头文件,因为这些文件具有 64 位编译环境的派生类型和数据结构的正确定义。

使用 lint 检查为 32 位和 64 位编译环境编写的代码。指定 -errchk=longptr64 选项以生成 LP64 警告。同时使用 -errchk=longptr64 标志来检查是否可将代码移植到下述环境中:长整型和指针的长度为 64 位而无格式整型的长度为 32 位。即使使用了显式强制类型转换,-errchk=longptr64 标志也会检查指针表达式和长整型表达式对无格式整型的赋值。

使用 -errchk=longptr64,signext 选项查找符合以下条件的代码:其中标准 ISO C 值保留规则允许在无符号整型表达式中使用带符号整型值的符号扩展。

如果只想检查要在 Oracle Solaris 64 位编译环境中运行的代码,请使用 lint-m64 选项。

lint 警告显示错误代码的行号、描述问题的消息以及是否涉及指针的说明。警告消息还指明涉及的数据类型的长度。如果确定涉及指针并且知道数据类型的长度,便可以查找特定的 64 位问题,并避免 32 位和更短类型之间的已有问题。

但请注意,尽管 lint 会提供有关潜在 64 位问题的警告,但也无法检测所有问题。另外在许多情况下,符合应用程序意图且正确无误的代码会生成警告。

通过在上一行中放置 "NOTE(LINTED("<optional message">))" 形式的注释,可以禁止对指定代码行发出警告。如果要 lint 忽略某些代码行(如强制类型转换和赋值),则此注释指令很有用。使用 “NOTE(LINTED(“<optional message”>))” 注释时请务必谨慎,因为它可能会掩盖真实问题。使用 NOTE 时,请包含 #include<note.h>。有关更多信息,请参阅 lint 手册页。