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)看起来更糟糕。
答案 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
是建议性的,而不是安全机制。)