"不得使用输入/输出库<stdio.h>."

Jea*_*dey 1 c++ coding-style

我正在阅读JSF AV C++编码标准,规则22说:

AV规则22(MISRA规则124,修订)

<stdio.h> 不应使用输入/输出库.

有没有理由不使用<stdio.h>

我知道这些规则适用于C++,我们可以使用<iostream>......但是有什么问题<stdio.h>

Jer*_*fin 5

最明显的问题是缺乏类型安全的printf,scanf以及它们的各种堂兄弟(例如sprintf).

除了类型安全问题外,这些scanfsprintf系列使得确保防止缓冲区溢出变得相当困难.它可以完成,但它并不是微不足道的,似乎只有极少数的C程序员可以完全了解如何处理这些类型的任务.


Chr*_*ckl 5

时不时地,会有这样的问题,关于为什么某些编码标准要求这样或那样。

正确的答案应该始终是:无论该编码标准的作者意图如何。有时,编码标准会给出其规则的理由;这个显然没有。因此,我们只能猜测您问题的答案可能是什么。

因此我将添加我自己的猜测:

飞行器听起来确实是一件严肃的事情,具有极高的正确性和稳健性要求。printfscanf人可以轻松编写可以顺利通过编译器但在运行时创建未定义行为的代码。

这些 C 函数确实比普通 C++ 流有一个优势:格式化字符串使编写国际化代码变得更容易。考虑这个快速制作的示例,使用std::ostream一些 UI 组件,例如客户管理应用程序中的按钮标签:

os << "Update customer\n";
Run Code Online (Sandbox Code Playgroud)

您可能想要动态添加客户的姓名:

os << "Update " << customer_name << "\n";
Run Code Online (Sandbox Code Playgroud)

您可能想动态插入“更新”的外语单词:

os << InternationalString(id_update) << " " << customer_name << "\n";
Run Code Online (Sandbox Code Playgroud)

然而,这本质上是以英语为中心的。它将产生正确的英语字符串,如“Update John”或“Update Joe”,但对于德语会失败,德语有不同的语法,需要“John aktualisieren”或“Joe aktualisieren”等字符串,且名称位于动词前面在这种情况下。

这就是格式字符串的亮点:

sprintf(s, FormatString(id_update_customer), customer_name);
Run Code Online (Sandbox Code Playgroud)

根据应用程序的语言设置,此类FormatString函数可能返回"Update %s""%s aktualisieren"

尽管如此,这仍然非常危险。事实上,如果customer_name在我上面的示例中是 a std::string,那么您已经有未定义的行为。

像Boost.Format这样的库尝试将格式字符串的灵活性与流的类型安全性结合起来。

回到你的实际问题,我的猜测是,国际字符串的灵活性并不是飞行器行业的一个大问题。


正如您所看到的,编码标准的每个方面都可以进行详细讨论。个别规则的原因可能并不总是那么明显,它们通常与编写标准的应用程序领域有关。

如果你不能问编码标准的作者,那么你的问题就无法真正得到回答。