5

使用 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 *),但这会在代码中的许多地方重复出现。

有没有办法通过选项或编译指示(或等效的东西)消除这个特定的警告?

4

2 回答 2

4

不,您不能关闭该警告。它告诉你你违反了类型系统。如果要调用func,则需要将指针传递给非易失性数据或更改函数签名以接受指向易失性数据的指针。

于 2012-08-28T16:56:37.253 回答
1

如果使用非限定指针访问volatile-qualified 对象,该标准允许编译器做任何他们喜欢的事情。这允许在某些平台上使用volatile-qualified 对象可能需要特殊指令才能访问它们,例如 write viavolatile uint16_t*可能会生成相当于以下内容的代码:

if ((uintptr_t)ptr >= 0xFFFF0000)
  __outport16(0xFFFF & (uintptr_t)ptr, value);
else
  (uint16_t*)ptr = value;

如果编译器编写者认为编译器应该只在晦涩的平台上利用这种自由,否则会很昂贵,并且应该在这样做几乎没有成本的平台上提供合理的行为,并且如果原始示例中的调用代码知道Y在执行期间没有外部实体将访问func,那么针对该编译器的代码将能够实现所需的行为而无需诊断,只需将 Y 的地址转换为float*. 不幸的是,维护 gcc 和 clang 的人似乎认为,当标准提到“不可移植或错误的构造”时,它的真正意思是“不可移植,即错误的构造”,而不是“不能移植到每个人的构造”符合宇宙中的机器,如果打算实现这种可移植性,那将是错误的。将指针转换为float*将使 gcc 或 clang 上的警告静音,但我不会指望它会导致它们产生合理的代码。

于 2017-09-28T22:08:49.943 回答