如何消除“丢弃限定符”警告?
使用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 *)
类型转换来消除它,但这在代码中的许多地方重复。
有没有办法消除这个特定的警告,有一个选项或一个pragma(或等效的东西)?
不,你不能关掉那个警告。 它告诉你你违反了类型系统。 如果要调用func
,则需要将指针传递给非易失性数据,或者更改函数签名以接受指向易失性数据的指针。
如果使用非限定指针访问volatile
限定对象,则标准允许编译器执行任何他们喜欢的操作。 这允许某些volatile
对象可能需要特殊指令来访问它们的平台,例如,通过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上的警告静音,但我不会指望它导致它们产生合理的代码。