使用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 *)
类型转换来消除它,但这会在代码中的许多地方重复。
有没有办法通过选项或编译指示(或等效的东西)消除此特定警告?
答案 0 :(得分:4)
不,你不能关掉那个警告。它告诉你你违反了类型系统。如果要调用func
,您需要将指针传递给非易失性数据,或者更改函数签名以接受指向易失性数据的指针。
答案 1 :(得分:1)
如果使用非限定指针访问volatile
限定对象,则标准允许编译器执行任何操作。这允许某些volatile
合格对象可能需要特殊指令来访问它们的平台,例如,通过volatile uint16_t*
写入可能会生成相当于:
if ((uintptr_t)ptr >= 0xFFFF0000)
__outport16(0xFFFF & (uintptr_t)ptr, value);
else
(uint16_t*)ptr = value;
如果编译器编写者采取的态度是编译器只应该在不起眼的平台上利用这些自由,那么这样做会很昂贵,并且应该在平台上提供合理的行为,这样做几乎不会花费任何东西,如果原始的调用代码示例知道在执行Y
期间没有外部实体将访问func
,然后代码定位该编译器将能够实现所需的行为而无需仅通过将Y的地址转换为a的诊断float*
。不幸的是,维持gcc和clang的人们似乎相信,当标准提到“非便携式或错误的结构”时,它实际上意味着“非便携式,即错误的”构造和#34;而不是那些不能移植到Universe中每个符合要求的机器上的构造,如果这样的可移植性是那么会错误的。将指针强制转换为float*
会使gcc或clang上的警告静音,但我不会指望它会导致它们产生合理的代码。