使用volatile字符串作为printf()的格式字符串

时间:2014-04-23 13:50:31

标签: c const volatile

假设我有以下函数签名:

int printf(const char * restrict format, ... );

现在,我有一个字符串定义如下:

volatile char command_str[256];

现在,当我想将此字符串传递给我的printf函数时,我将收到以下警告:

Warning 32  [N] 2943 : passing 'volatile char [256]' to parameter of type 'const char *' discards qualifiers    C:\P\parameter\parameter.c

我不想更改printf签名,让警告消失的最简单方法是

printf((const char*)command_str, .......);

我觉得这不是最好的解决方案。什么是正确的做法?我无法使command_str非易失性,因为它是在中断中访问的。

2 个答案:

答案 0 :(得分:7)

const签名中的printf()声明了一个承诺printf(),它不会使format指向的数据混乱(因此,可以为char*)传递const char*format个变量。

现在,你的数组是volatile(我希望你知道它的含义)。编译器警告您,printf()范围内的这种波动性被丢弃 - 您无法获得对 format 内访问的易失性语义{1}}。

作为建议做什么,我会说评估您是否确实希望对数据进行更改 - printf()。我无法找到理由,因此制作本地副本听起来很合理。

答案 1 :(得分:4)

函数传递给(printf())期望字符串是可变的(const *意味着printf()不会修改内容,不会混淆!),以及你试图传递的字符串将被中断修改(好吧,确切地说是指向字符串的指针)。

你怎么能确保中断不会修改你打电话printf()printf()实际打印......之间的字符串内容?在 printf()工作时,什么阻止了发生中断?

您需要在调用printf()(使用ASM {"CLI"}或更适用于您的平台的内容)时屏蔽中断,或者只是将传递的字符串复制到printf()

// point a
char s[256];
strncpy(s, command_str, 256);
// point b
printf("%s", s);
// point c

这将解决printf()的问题,但现在您有一个新的竞争条件点 a b 。我认为你需要重构你的代码。你有更大的问题。

一种解决方案可能是:

char s[256];
mask_interrupts();
strncpy(s, command_str, 256);
unmask_interrupts();
printf("%s", s");