2017-10-05 2 views
3

Le code suivant compile propre sur GCC, mais obtient une erreur sur Clang:Comment éliminer la constité sur un pointeur de fonction?

typedef void (MyFuncPtr)(); 
void foo(const MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

erreur Clang:

error: cannot initialize a variable of type 'MyFuncPtr *' (aka 'void (*)()') with an lvalue of type 'const MyFuncPtr *' 
    (aka 'void (const *)()') 

J'ai essayé les solutions suivantes et ils ont tous obtenir des erreurs, sauf pour le style C exprimés:

const_cast:

MyFuncPtr* myTestPtr = const_cast<MyFuncPtr*>(ptr); 

Erreur:

error: const_cast to 'MyFuncPtr *' (aka 'void (*)()'), which is not a reference, pointer-to-object, or pointer-to-data-member 

reintepret_cast:

MyFuncPtr* myTestPtr = reinterpret_cast<MyFuncPtr*>(ptr); 

Erreur:

error: reinterpret_cast from 'const MyFuncPtr *' (aka 'void (const *)()') to 'MyFuncPtr *' (aka 'void (*)()') casts away 
    qualifiers 

fonte style C:

MyFuncPtr* myTestPtr = (MyFuncPtr*) ptr; 

succès!

Questions:
Pourquoi const_cast ne fonctionne-t-il pas sur les pointeurs de fonction?
L'utilisation d'un cast de style C est-elle la seule solution?
Pourquoi cela fonctionne-t-il sur GCC sans casting?

Merci d'avance!

VERSIONS Compilateur:
* G ++ version 4.6.3
* version clang 3.5.0.210790

+0

Le type 'const MyFuncPtr *' est presque un non-sens et tout aussi inutile (comme presque totalement inutile). Et chaque utilisation à laquelle je peux penser n'a pas de * instance * associée. Pourquoi avez-vous ce type dans votre programme? Code trop générique? – Yakk

+3

note que 'MyFuncPtr' est en fait un type de fonction, pas un type de pointeur de fonction (Mais cela n'invalide pas votre question, en fait cela le rend plus intéressant) –

Répondre

3

Dans votre code, MyFuncPtr est un type de fonction (pas un type pointeur de fonction). Votre code essaie d'utiliser le type const MyFuncPtr, qui applique const à un type de fonction.

Cependant, d'après la note en C++ 14 [dcl.fct]/6, il n'y a pas une telle chose comme un type de fonction const qualifié:

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. —end note ]

Cette section parle principalement sur les cv-qualifier-seq, qui sont les qualificatifs qui se produisent après une fonction membre. Cependant, en passant, il semble spécifier que les qualificatifs cv appliqués à un type de fonction en général sont ignorés.

Donc, votre code devrait être le même que:

typedef void (MyFuncPtr)(); 
void foo(MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

qui signifierait clang est mis sur écoute pour signaler une erreur.

+0

J'utilise C++ 11 dans ce cas, cela affecte-t-il votre répondre? – Chadness3

+0

Sur clang version 3.7 je commence à obtenir l'avertissement suivant qui correspond à la réponse ci-dessus: 3: : 3: 10: avertissement: qualificateur 'const' sur le type de fonction 'MyFuncPtr' (aka 'void()') n'a aucun effet [ -Wignored-qualifiers] void foo (const MyFuncPtr * ptr) – Chadness3

+0

@ Chadness3 OK, on ​​dirait que clang a déjà trouvé le bogue dans 3.5 et l'a corrigé pour 3.7 –