MISRA C 的 printf() 替代方案:2004 兼容代码

问题描述

首先,如果问题中有任何语法错误,我想道歉。

说到点子上,我对使用 MISRA C 指南进行编码有点陌生,

遵循 MISRA C 2004 中的两条规则:

规则 16.1(必需):函数不应使用可变数量的 论据。 规则 20.9(必需):输入/输出 不得用于 生产代码

这显然意味着我不能在生产代码中使用 ->len(node.xpath('./article/div[@class="flex-Box"]/a/span[starts-with(@class,"grid-Box")]')) ->1 ->node.xpath('./article/div[@class="flex-Box"]/a/span[starts-with(@class,"grid-Box")]')[0] -><Element span at 0x1ac51134040> 使其符合 MISRA C,因为 printfprintf 的一部分并允许可变数量的参数,所以我开始寻找如何编写我自己的 <stdio.h> 语句,到目前为止我无法找到任何解决此困境的方法,我们将不胜感激其他开发人员的帮助。

解决方法

到目前为止,我无法找到解决此困境的任何方法

您必须使用一次打印一个(可数)事物的函数。您可能想要实现的示例接口可能如下所示:

print_string("Hello");
print_int(5);
print_char('\n');
,

所以我开始寻找如何编写自己的 printf 语句

大多数 MISRA-C 系统是嵌入式系统,其中 db.employees.aggregate([ { $match: {'_id': 5}},{ $unwind: '$events'},{ $match: {'events.start': 2} ]); 只是围绕 UART 库的一些臃肿的包装器。通常的解决方案是开发您自己的日志记录/消息传递工具。不一定是基于 UART 的,也可以是其他一些串行总线,或者只是 8 个并行数据或一些 LCD/7 段......所有这一切都取决于您需要显示的内容以及您是否打算将其作为生产代码的一部分与否。

因此,如何做到这一点是高度特定于项目的,通常更多的是系统设计和电子问题,而不是编程问题。

编辑

由于您似乎在制作某种通用库,因此一种解决方案是简单地提供一个将字符串返回给调用者的 API,然后让调用者担心如何呈现它们。这使您的 lib MISRA-C 兼容,同时允许调用者以他们可用的任何特定于应用程序的方式打印字符串。例如:

printf

其中“lib”是您的库的一些前缀。将字符串分配留给调用者。或者,老式的方式:

void lib_getmsg (char* msg,size_t bufsize);

这将返回一个指向您的库分配的内部 lib_result_t lib_dosomething (void); // Returns LIB_OK if went OK,returns LIB_ERR in case of errors. // To get more information,call lib_get_lastmsg. const char* lib_get_lastmsg (void); 字符串的指针。这样做的缺点是它在多进程环境中不能很好地工作。

,

您需要了解 MISRA C 指南的基本原理,了解它们的使用环境以及您自己的代码的环境。

您还需要了解 MISRA 指南不能盲目遵循勾选框的心态……然后您需要意识到 MISRA 的那些好人在实际指南之前提供了几章有用的材料。其中一部分是偏差程序。

如果您能证明您认为需要违反准则的原因,请使用指定的偏差程序。这需要您了解违规行为的性质,以及您将如何确保应用程序的完整性。

如果您确实需要使用 printf() 并且您可以证明这一点,请使用偏差

,

在 Linux 上,在现代 x86_64 处理器上运行:

int main()
{
    char *s = "Hello,World!\n";
    long l = 14;
    long fd = 1;
    long syscall = 1;
    long ret = 0;
    __asm__("syscall"
            : "=a"(ret)
            : "a"(syscall),"D"(fd),"S"(s),"d"(l));
    return 0;
}

输出:

Hello,World!