Avertissement explicite d’ignorance de -Wcast-qual: la conversion supprime le qualificatif ‘__atsortingbute __ ((const))’ ‘du type cible du pointeur

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

L’extrait "warning: cast discards '__atsortingbute__((const))' qualifier from pointer target type [-Wcast-qual]" ci-dessus générera le "warning: cast discards '__atsortingbute__((const))' qualifier from pointer target type [-Wcast-qual]" . J’aime -Wcast-qual car cela peut m’aider à écrire accidentellement dans la mémoire, je ne devrais pas écrire.

Mais maintenant, je ne veux pas utiliser const pour une seule occurrence (pas pour le fichier ou le projet complet). La mémoire sur laquelle elle pointe est accessible en écriture (comme précédemment). Je préférerais ne pas laisser const de ptr car il est utilisé ailleurs et garder les pointeurs (un const et un non-const) semble être une idée pire.

    Dans GCC 4.2 et versions ultérieures, vous pouvez supprimer l’avertissement d’une fonction en utilisant #pragma. L’inconvénient est que vous devez supprimer l’avertissement dans toute la fonction. vous ne pouvez pas l’utiliser uniquement pour certaines lignes de code.

     #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 

    L’avantage est que l’ensemble de votre projet peut utiliser les mêmes options d’avertissement / vérification des erreurs. Et vous savez exactement ce que fait le code, et obligez simplement GCC à ignorer une vérification explicite d’un morceau de code.
    En raison de la limitation de ce pragma, vous devez extraire le code essentiel de la fonction actuelle vers la nouvelle, et rendre la nouvelle fonction seule avec ce #pragma.

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

    Ou, sans stdint.h:

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

    Tant que vous êtes d’accord avec le code spécifique à GCC / clang, cela devrait faire l’affaire:

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

    Vous pouvez également utiliser une version modifiée basée sur Est-ce que la conversion du pointeur en union anonyme est valide dans C11? :

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

    Un peu en retard, mais vous pouvez également le faire sans vous tromper d’avertissements:

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

    Vous vous retrouvez avec q = buf + ptr - buf = ptr + buf - buf = ptr , mais avec la buf de buf .

    (Oui, cela vous permet de supprimer const de n’importe quel pointeur; const est un conseil, pas un mécanisme de sécurité.)