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

时间:2012-11-06 11:10:43

标签: c gcc warnings

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

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

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

4 个答案:

答案 0 :(得分:8)

#include <stdint.h>

const char * ptr = buf;
....
char * p = (char *)(uintptr_t)ptr;

或者,没有stdint.h:

char *  p = (char *)(unsigned long)ptr;

答案 1 :(得分: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

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

答案 2 :(得分:0)

只要您对GCC / clang特定的代码满意,那么this应该可以完成此工作:

#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
#define CONST_CAST(TYPE,X) CONST_CAST2 (TYPE, const TYPE, (X))

const char *ptr = buf;
char *q = CONST_CAST(char *, ptr);

或者,基于Is cast of pointer to anonymous union valid in C11?的修改版本:

#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((union {FROMTYPE _q; TOTYPE _nq;}){._q=constBoo}._nq)

答案 3 :(得分:-1)

迟到了,但你也可以这样做而不会发出任何警告:

static char buf[8];
void foo(){
    const char* ptr = buf;
    /* ... */
    char* q = buf + (ptr-buf);
}

您最终得到q = buf + ptr - buf = ptr + buf - buf = ptr,但buf的常量。

(是的,这允许您从任何指针中删除const; const是建议性的,而不是安全机制。)