使用GCC和C99模式,我有一个函数声明为:
void func(float *X);
当我调用这个函数时,我使用了一个易失性数组Y:
volatile float Y[2];
int main()
{
func(Y);
return 0;
}
在编译(使用-Wall
)时,我收到以下警告:
warning: passing argument 1 of ‘func’ discards qualifiers from pointer target type
blah.c:4: note: expected ‘float *’ but argument is of type ‘volatile float *’
我可以通过显式的(float *)
类型转换来消除它,但这在代码中的许多地方都是重复的。
有没有一种方法可以消除这个特定的警告,用一个选项或一个杂注(或类似的东西)?
发布于 2012-08-29 00:56:37
不,你不能把警告关掉。它会告诉你你违反了类型系统。如果要调用func
,则需要向其传递指向非易失性数据的指针,或者更改函数签名以接受指向易失性数据的指针。
发布于 2017-09-29 06:08:50
如果使用非限定指针来访问volatile
-qualified对象,则标准允许编译器做任何他们喜欢做的事情。这允许某些volatile
-qualified对象可能需要特殊指令才能访问它们的平台,例如,通过volatile uint16_t*
写入可能会生成等同于以下内容的代码:
if ((uintptr_t)ptr >= 0xFFFF0000)
__outport16(0xFFFF & (uintptr_t)ptr, value);
else
(uint16_t*)ptr = value;
如果编译器编写者认为编译器应该只在晦涩的平台上利用这些自由,否则这样做的代价将是昂贵的,并且应该在这样做几乎不会花费任何成本的平台上提供合理的行为,并且如果原始示例中的调用代码知道在func
执行期间没有外部实体将访问Y
,那么针对该编译器的代码将能够在没有诊断的情况下实现所需的行为,只需将Y的地址转换为float*
即可。不幸的是,维护gcc和clang的人似乎认为,当标准提到“不可移植的或错误的构造”时,它实际上是指“不可移植的,即错误的构造”,而不是“不能移植到宇宙中每一台符合标准的机器上的构造,如果这种可移植性是有意的,那么这将是错误的。将指针指向float*
将使关于gcc或clang的警告静默,但我不指望它会导致它们产生合理的代码。
https://stackoverflow.com/questions/12163969
复制相似问题