☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

在 C++ 代码中禁用 C 字符串格式化方法

10.6.9 ID_forbidCStringFormat
目录 › next › previous

C 字符串格式化方法的主要问题有:

  • 需要手工维护参数与格式化占位符的对应关系
  • 在编译期难以保证安全性,增加测试成本
  • 与 C++ 的强类型理念不符,不在 C++ 标准之内
  • 只接受基本类型的参数,不利于数据的对象化管理

故在 C++ 代码中禁用下列函数:

printf、fprintf、sprintf、snprintf、
wprintf、fwprintf、swprintf、
vprintf、vfprintf、vsprintf、vsnprintf、
vwprintf、vfwprintf、vswprintf

示例:

typedef int32_t mytype;

struct T {
    mytype a;
};

void foo(const T* p) {
    printf("%d", p->a);   // Non-compliant, unportable
}

在 C 字符串格式化方法中,不同类型的参数依赖不同的格式化占位符,参数的类型与个数必须和占位符严格对应,否则就会导致未定义的行为,当参数较多时极易出错,单纯地要求开发者小心谨慎是不可靠的,改用更安全的方法才是明智的选择。

在 C++ 代码中利用标准流可避免这些问题,而且 C++ 标准流具备可扩展性,符合面向对象的编程理念:

std::ostream& operator << (std::ostream& os, const T& t) {
    return os << t.a;
}

void foo(const T* p) {
    std::cout << *p;     // Compliant, safe and brief
}

当参数较多时,标准流的方式在形态上可能较为“松散”,在可读性上可能不如 printf 函数,而且重载 <<、>> 运算符的方式也会产生同步问题和额外的性能开销,对此 C++20 的“std::format”提供了更多的格式化方法。也可参见 ID_forbidVariadicFunction 的示例,用“模板参数包”等更安全的方法实现 printf 函数的功能。

相关

ID_forbidVariadicFunction

依据

ISO/IEC 9899:1999 7.19.6.1(2)-undefined ISO/IEC 9899:1999 7.19.6.1(9)-undefined ISO/IEC 9899:2011 7.21.6.1(2)-undefined ISO/IEC 9899:2011 7.21.6.1(9)-undefined

参考

C++ Core Guidelines SL.io.3
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.