1.1 可移植性是一种考虑问题的方式,而不是一种状态 1
第1章 可移植性概念 1
1.2 培养良好的可移植性编程习惯 2
1.3 良好的习惯胜过故障或标准的具体知识 2
1.3.1 尽早经常移植 3
1.3.2 在不同的环境中开发 3
1.3.3 使用不同的编译器 4
1.3.4 在多个平台上进行测试 4
1.3.5 支持多个程序库 4
1.4 为新项目规划可移植性 5
1.4.1 使可移植性变得容易 5
1.4.2 选择可移植性的合理水平 5
1.4.3 不要将项目变成专有产品 7
1.5.2 只做最低限度必要的改动 9
1.5.3 规划攻击目标 9
1.5 移植旧程序 9
1.5.1 除非程序已经被移植,否则就认定该程序是不可移植的 9
1.5.4 在修改控制程序中记录每一件事 10
第2章 ANSI C与C++ 11
2.1 选择C和C++语言的理由 11
2.1.1 C和C++提供了低级访问 11
2.1.2 C与C++编译成本机代码 12
2.2 C与C++的术语 12
2.3 可移植性与C/C++ 13
第3章 可移植性技术 17
3.1 避免使用新特性 17
3.2 处理变化的特性 18
3.3 使用安全的串行化和反串行化 21
3.4 综合测试 23
3.5.1 编译时断言 25
3.5 使用编译选项 25
3.5.2 严格编译 26
3.6 从可移植文件中隔离平台相关文件 26
3.7 编写简单明了的代码 27
3.8 使用唯一的名称 27
3.9 实现抽象 29
3.9.1 分派抽象 30
3.9.2 抽象数据类型(typedef) 35
3.9.3 使用C预处理程序 37
3.9.4 对无法预料的事情做好准备 38
3.9.5 传输与系统相关的信息 39
3.9.6 桥接函数 41
3.10.1 避免使用自修改代码/动态生成代码 42
3.10 低级编程 42
3.10.2 保持高级后退 46
3.10.3 关键字register 47
3.10.4 外部与嵌入式asm文件 48
第4章 编辑与源代码控制 51
4.1 文本文件行结束格式之间的差异 51
4.2 可移植的文件名 53
4.3 源控制 53
4.3.1 源控制系统 54
4.3.2 通过代理程序迁出 56
4.4 构建工具 57
4.4.1 平台特有的构建工具 57
4.4.2 可移植的构建工具 58
4.5 编辑器 61
4.6 本章小结 62
5.1 对齐 63
第5章 处理器的不同之处 63
5.2 字节排序和Endianess 66
5.2.1 Big-Endian值与Little-Endian值的比较 66
5.2.2 标准化存储格式 68
5.2.3 固定的网络字节排序 69
5.3 带符号整数的表示方法 70
5.4 本地类型的大小 70
5.5 地址空间 74
5.6 本章小结 75
第6章 浮点 77
6.1 浮点的历史 77
6.2 标准的C与C++浮点支持 78
6.3.1 不一致的评估 79
6.3 浮点的问题 79
6.3.2 浮点与联网应用程序 80
6.3.3 转换 81
6.4 定点整数数学 82
6.5 从浮点数中析取整数位 82
6.6 实现查询 85
6.7 异常结果 87
6.7.1 特殊值 88
6.7.2 异常 89
6.7.3 浮点环境访问 89
6.8 存储格式 90
6.9 本章小结 91
第7章 预处理程序 93
7.1 预定义符号 93
7.2 头文件 95
7.2.2 头文件名 96
7.2.1 头文件的路径规范 96
7.3 配置宏 97
7.4 条件编译 98
7.5 Pragma 99
7.6 本章小结 99
第8章 编译器 101
8.1 结构大小、填充和对齐 101
8.2 内存管理的特性 104
8.2.1 释放的影响 104
8.2.2 对齐的内存分配 104
8.3 堆栈 105
8.3.1 堆栈的大小 105
8.4 printf()例程 106
8.3.2 alloca()的问题 106
8.5 类型尺寸与行为 107
8.5.1 64位整数类型 107
8.5.2 基本类型的尺寸 108
8.5.3 有符号与无符号的char类型 110
8.5.4 作用如同int的enum 111
8.5.5 数字常量 112
8.5.6 有符号与无符号的右移 112
8.6 调用约定 113
8.6.1 名称修饰 114
8.6.2 函数指针与回调 114
8.6.3 可移植性 115
8.7 返回结构 116
8.8 Bitfield 116
8.9 注释 117
8.10 本章小结 118
第9章 用户交互作用 119
9.1 用户界面的演变 119
9.1.1 命令行 119
9.1.2 窗口系统 120
9.2 本机GUI与应用程序GUI的比较 121
9.3 低级图形 121
9.4 数字音频 122
9.5 输入 123
9.5.1 键盘 123
9.5.2 鼠标 123
9.6 跨平台工具箱 124
9.7 本章小结 124
9.5.3 操纵杆与游戏键盘 124
第10章 联网 125
10.1 网络协议的演化 125
10.2 编程接口 126
10.2.1 套接字 126
10.2.2 RPC(远程过程调用)与RMI(远程方法调用) 128
10.2.3 分布式对象 129
10.3 本章小结 129
第11章 操作系统 131
11.1 操作系统的演化 131
11.2 宿主环境与独立式环境 132
11.3 操作系统可移植性的悖论 132
11.4 内存 133
11.4.1 内存限制 133
11.4.2 内存映射 133
11.4.3 受保护内存 134
11.5 进程与线程 135
11.5.1 进程控制与通信函数 135
11.5.2 IPC(进程间通信) 135
11.5.3 多线程技术 136
11.6 环境变量 140
11.7 异常处理 141
11.7.1 C异常处理 141
11.7.2 C++异常处理 142
11.8 用户数据存储 142
11.8.1 Microsoft Windows注册表 143
11.8.2 Linux用户数据 144
11.8.3 OS X的首选项 144
11.9.2 特权目录与数据 145
11.9.1 应用程序安装 145
11.9 安全与许可 145
11.9.3 低级访问 146
11.10 本章小结 146
第12章 动态库 147
12.1 动态链接 147
12.2 动态加载 148
12.3 共享库的问题(亦称为DLL地狱) 148
12.3.1 版本问题 148
12.3.2 扩散 150
12.4 Gun LGPL 150
12.5 Windows DLL 150
12.6 Linux的共享对象 153
12.7 Mac OS X架构、插件与捆绑 154
12.7.1 架构 154
12.7.2 捆绑 155
12.7.3 插件 156
12.8 本章小结 157
第13章 文件系统 159
13.1 符号链接、快捷方式与别名 159
13.1.1 Windows的LNK文件 160
13.1.2 Unix的链接 160
13.2 路径规范 160
13.2.1 磁盘驱动器与卷说明符 161
13.2.2 路径分隔符与其他特殊字符 161
13.2.3 当前目录 161
13.2.4 路径长度 162
13.2.5 区分大小写 162
13.3 安全性与访问权限 162
13.6 特殊目录 164
13.5 文件属性 164
13.4 Macintoch的古怪行为 164
13.7 文本处理 165
13.8 C运行时库与可移植文件访问 165
13.9 本章小结 166
第14章 可扩缩性 167
14.1 较好的算法等于较好的可扩缩性 167
14.2 可扩缩性的局限性 168
14.3 本章小结 169
第15章 可移植性与数据 171
15.1 应用程序数据与资源文件 171
15.1.1 二进制文件 171
15.1.2 文本文件 171
15.1.3 XML 173
15.2 创建可移植的图形 174
15.1.4 作为数据文件的脚本语言 174
15.4 本章小结 175
15.3 创建可移植的音频 175
第16章 国际化与本地化 177
16.1 字符串与统一代码标准 177
16.2 货币 179
16.3 界面元素 180
16.4 本章小结 180
第17章 脚本语言 183
17.1 脚本语言的一些缺点 184
17.2 JavaScript/ECMAScript 184
17.3 Python 185
17.5 Ruby 186
17.6 本章小结 186
17.4 Lua 186
第18章 跨平台的程序库与工具包 187
18.1 库 187
18.2 应用程序架构 188
18.2.1 Qt 188
18.2.2 GTK+ 188
18.2.3 FLTK 188
18.2.4 wxWidgets 189
18.3 本章小结 189
附录A 可移植开源装置(POSH) 191
A.1 POSH的预定义符号 191
A.2 POSH的固定大小类型 192
A.3 POSH的实用函数和宏 193
附录B 用于可移植性的规则 197