8
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上面一样)。我宁愿不删除 const ,ptr因为它在其他地方使用并且保持指针(一个 const 和一个非常量)似乎是一个更糟糕的主意。

4

4 回答 4

9
#include <stdint.h>

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

或者,没有 stdint.h:

char *  p = (char *)(unsigned long)ptr;
于 2015-07-29T14:01:56.853 回答
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 单独创建新函数。

于 2012-11-06T15:17:27.283 回答
0

只要您对 GCC/clang 特定代码没问题,那么应该可以完成工作:

#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 在 C11 中有效吗?

#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((union {FROMTYPE _q; TOTYPE _nq;}){._q=constBoo}._nq)
于 2018-07-08T12:10:21.293 回答
-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是建议性的,而不是安全机制。)

于 2014-12-20T20:47:20.053 回答