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を1回だけ(ファイルまたはプロジェクト全体ではなく)キャストします。それが指しているメモリは書き込み可能です(buf上記のように)。ptrconstは他の場所で使用されており、ポインター(1つのconstと1つのnon-const)を保持することは、より悪い考えのように思われるため、私は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を使用して新しい関数だけを作成する必要があります。

于 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);

または、匿名共用体へのポインタのキャストは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'sconstnessになります。

(はい、これによりconst、任意のポインターから削除できます。これconstは助言であり、セキュリティメカニズムではありません。)

于 2014-12-20T20:47:20.053 に答える