假设我有以下函数签名:
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
非易失性,因为它是在中断中访问的。
答案 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");