我刚开始使用MISRA C指南进行编码。
以下是MISRA C 2004中的两个规则:
规则16.1 (必须满足):函数不应定义为可变数量的参数。
规则20.9 (必须满足):生产代码中不应使用输入/输出库<stdio.h>
。
这意味着我不能在生产代码中使用<stdio.h>
中的printf
,因为它允许一个可变数量的参数。因此,我开始寻找如何编写自己的printf
语句。到目前为止,我无法找到任何解决方案。希望能得到其他开发者的帮助。
我刚开始使用MISRA C指南进行编码。
以下是MISRA C 2004中的两个规则:
规则16.1 (必须满足):函数不应定义为可变数量的参数。
规则20.9 (必须满足):生产代码中不应使用输入/输出库<stdio.h>
。
这意味着我不能在生产代码中使用<stdio.h>
中的printf
,因为它允许一个可变数量的参数。因此,我开始寻找如何编写自己的printf
语句。到目前为止,我无法找到任何解决方案。希望能得到其他开发者的帮助。
迄今为止,我无法找到解决这个困境的任何方案。
你需要使用每次仅打印一件事物的函数。您可能想要实现的示例接口可能如下所示:
print_string("Hello");
print_int(5);
print_char('\n');
print_int
和其他函数是抽象函数,展示了可能要实现的接口示例。不过,实现可以是可移植的,只有putchar
部分是特定于实现的。 - KamilCuk所以我开始寻找如何编写自己的printf语句
大多数MISRA-C系统都是嵌入式系统,其中printf
只是一个笨重的UART库包装器。通常的解决方案是开发自己的日志/消息工具。不一定是基于UART的,也可以是其他串行总线,或者只是8个并行数据或一些LCD / 7-seg…这完全取决于您需要显示的内容以及是否打算将其作为生产代码的一部分。
因此,如何做到这一点高度依赖于项目,并且通常更多地是系统设计和电子问题,而不是编程问题。
编辑
由于您似乎正在制作某种通用库,因此一种解决方案是简单地提供API,该API返回字符串给调用者,然后让调用者担心如何呈现它们。这使得您的lib符合MISRA-C标准,同时允许调用者以他们可用的任何应用程序特定方式打印字符串。例如:
void lib_getmsg (char* msg, size_t bufsize);
这里的“lib”是你的库的一些前缀。字符串分配留给调用者处理。或者可以选择传统的方式:
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!