来自-Wcast-qual的显式忽略警告:从指针目标类型抛出'__ attribute __((const))'限定符

ext*_*ext 8 c gcc warnings

static char buf[8];
void foo(){
    const char* ptr = buf;
    /* ... */
    char* q = (char*)ptr;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段将生成"warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]".我喜欢,-Wcast-qual因为它可以帮助我不小心写入内存,我不应该写.

但是现在我想抛弃const只出现一次(不是整个文件或项目).它指向的内存是可写的(就像buf上面一样).我宁愿不删除const,ptr因为它在别处使用并且保持指针(一个const和一个非const)似乎是一个更糟糕的主意.

Bru*_*e K 9

#include <stdint.h>

const char * ptr = buf;
....
char * p = (char *)(uintptr_t)ptr;
Run Code Online (Sandbox Code Playgroud)

或者,没有stdint.h:

char *  p = (char *)(unsigned long)ptr;
Run Code Online (Sandbox Code Playgroud)

  • 抑制通常不可移植。如果你分享你的代码,有人会用讨厌你的抑制方法的东西来编译。如果你想明确:#define UN_CONSTIFY(_t, _v) ((_t)(uintptr_t)(_v)) (2认同)

jcl*_*lin 5

在GCC 4.2及更高版本中,您可以使用#pragma来禁止函数警告.缺点是你必须在整个功能中抑制警告; 你不能只将它用于某些代码行.

#pragma GCC diagnostic push  // require GCC 4.6
#pragma GCC diagnostic ignored "-Wcast-qual"
void foo(){
    const char* ptr = buf;
    /* ... */
    char* q = (char*)ptr;
}
#pragma GCC diagnostic pop   // require GCC 4.6
Run Code Online (Sandbox Code Playgroud)

优点是您的整个项目可以使用相同的警告/错误检查选项.并且您确实知道代码的作用,并且只是让GCC忽略对一段代码的一些显式检查.
因为这个pragma的局限性,你必须从当前函数中提取基本代码到新函数,并使用这个#pragma单独创建新函数.

  • **默认警告启用:GNU编译器集合(GCC)4.6.3可能会生成默认情况下无法禁止的警告.**`-Wcast-qual`就是其中之一:`warning:initialization discards'const'限定符来自指针目标类型**[默认启用]**` (4认同)
  • @AlterMann:当您进行**隐式**转换时会出现一个完全不同的警告,该转换会丢弃“const”限定符(这是无效的C;C没有这样的隐式转换)。这不是OP看到的警告。 (2认同)