A. 代码从C语言到C++语言的移植
A.1 字符常量
注解
在C中,字符常量是int类型,而在C++中,其类型为char.
示例
I = sizeof(‘a’);
在C中,i保存的实际内容是sizeof(int)的计算结果值,该值要比1大。而在C++中,i存储的实际内容是sizeof(char),该值总是为1.
准则
当将C代码移植为C++代码时,所有对字符常量的sizeof有依赖关系的表达式都要被移除。
A.2 文件范围内的对象声明
注解
在C++中,在文件范围内,声明一个没有指定存储类型标志符的对象时,实际上是定义该对象为外部链接符号(extern)。如果这个定义中没有初始化表达式,那么该对象将被初始化为0.相比较于C来说,C++程序中声明的对象会被明确的定义且只定义过1次。
而在C中,这将被视为一个暂时的定义,这种定义方式在一个translation unit中允许出现多次。
示例
int a; /* (1) */
int a = 10; /* (2) */
在C中,(1)是一种暂时性的定义。由于(2)被看作是确切的定义,(1)被看作是只是声明一个变量。
在C++中,(1)、(2)都被认为是定义式。由于存在(1)、(2)两个重复定义式,因此是一个错误。
准则
在C++中,如果想在文件范围内仅声明一个对象(而不是定义该对象),那么该对象不能拥有初始化表达式,并且需要使用extern来修饰。
声明于文件范围内的每一个对象只能显式的被定义一次。除了一次声明外,其余所有声明都必须具有extern修饰并且没有初始化表达式。
A.3 const 类型修饰符
注解
在C中,在文件范围内,一个使用const修饰而未指明存储类型的对象具有外部链接属性。而在C++中,它具有内部连接属性。
示例
+- file1 --------------------+
| extern const int n; |
+----------------------------+
+- file2 --------------------+
| const int n = 10; |
+----------------------------+
在C中,文件file2中的对象n具有外部连接属性,因此,文件file1中对象n(该对象同样具有外部链接属性)可以引用它。在C++中,文件file2中的对象n具有的属性是内部链接的,因此,file1中的对象n无法引用到它。
准则
使用extern显示修饰const对象,使该对象具有外部链接属性。
A.4 void*的转型
注解C语言标准允许void*转换为T*(T表示任何对象),而在C++中没有这样的标准。在C++中类似的转换需要显示转换来完成。
下面这些C标准库函数都返回void*:
calloc, malloc, realloc, bsearch, memcpy, memmove,
memchr, memset
在C++中,将这些函数的返回值赋值给一个非void*的指针时,需要显示转换。
示例
int* p;
p = malloc(10 * sizeof(int));
在C++中,对指针p的赋值需要显示的转换,如:
p = (int *)malloc(10 * sizeof(int));
准则
在C++中使用new来代替calloc、malloc、realloc(参考A.12);
忽略memcpy, memmove, 以及memset的返回值(通常这些返回值由函数的第一个参数转换而来);对于其他所有返回void*函数(包括标准库函数和用户自定义函数),需要使用显式的转换来将返回值转换为其他指针类型。