Явное предупреждение об игнорировании из -Wcast-qual: отбрасывает «__attribute __ ((const))» квалификатор из целевого типа указателя

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

Вышеприведенный fragment будет генерировать "warning: cast discards '__attribute__((const))' qualifier from pointer target type [-Wcast-qual]" . Мне нравится -Wcast-qual так как он может помочь мне случайно записать в память, я не должен писать.

Но теперь я хочу отбросить const только для одного события (не для всего файла или проекта). Память, на которую он указывает, доступна для записи (как и buf выше). Я бы предпочел не отбрасывать const из ptr поскольку он используется в другом месте и придерживается указателей (один const и один не const const), кажется, хуже.

В 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.

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

Или, без stdint.h:

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

Пока вы в порядке с 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, указана на анонимный союз, действительный в C11? :

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

Немного поздно, но вы также можете сделать это, не опускаясь с предупреждениями вообще:

 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 – консультативный, а не механизм безопасности.)