接口的参数类型和返回类型不应为 void*
6.4.4 ID_forbidFunctionVoidPtr
与接口相关的数据类型应保持精确,不应将参数类型或返回类型设为 void*。
在 C++ 代码中,如果参数或返回值需要面对多种不同类型的数据,应合理使用重载或模板机制。
示例:
class A {
public:
void* foo(); // Non-compliant
void bar(void*); // Non-compliant
};
例中 foo 和 bar 函数的返回值以及参数是不符合要求的。
C 语言中存在大量的库函数不符合本规则要求,在 C++ 代码中应避免使用,如:
int buf[123];
memset(buf, 0, 123); // Logic error, should be ‘123 * sizeof(int)’
例中 memset 函数的第一个形式参数就是 void* 型,只能通过更底层的二进制方式访问对象序列,是一种对类型设计的破坏,应改用 STL 标准库提供的方法:
int buf[123];
std::fill_n(buf, 123, 0); // Safe and brief
改用类型明确的方法可以使很多问题在编译期得到控制。
例外:
struct T {
void* operator new(size_t); // Compliant
void operator delete(void*); // Compliant
};
C++ 语言规定 new 运算符的返回类型为 void*,delete 运算符的参数类型为 void*,这些情况可不受本规则约束。