2017-08-16 7 views
5
#include <stdio.h> 
#include <cstddef> 
#include <cstring> 

namespace /*namespace name generated by compiler*/ 
{ 
    struct BB{}; 
} 

struct AA{}; 

namespace my 
{ 
    inline void * memcpy(void*, const void*, std::size_t) 
    { 
     puts("CUSTOM IMPLEMENTATION"); 
     return 0; 
    } 
} 

namespace my 
{ 
    void func() 
    { 
     AA a; 
     memcpy(&a, &a, sizeof(a)); // ambigious call for g++4.7 - g++6.2 

     BB b; 
     memcpy(&b, &b, sizeof(b)); // unambigious call 

    } 
} 

int main(int, char **) 
{ 
    my::func(); 
    return 0; 
} 

Pourquoi memcpy est appel ici mal assurés?recherche dans C non qualifié ++

Veuillez jeter un oeil à l'exemple avec la variable "i" dans ANSI ISO CEI 14882, C++ 2003, 3.4.1, (6) (page 30). Il "prouve" qu'il n'y a pas d'ambigiotie dans une telle construction.

namespace A { 
    namespace N { 
    void f(); 
    } 
} 
void A::N::f() { 
    i = 5; 
// The following scopes are searched for a declaration of i: 
// 1) outermost block scope of A::N::f, before the use of i 
// 2) scope of namespace N 
// 3) scope of namespace A 
// 4) global scope, before the definition of A::N::f 
} 

Les règles de recherche non qualifiées ont-elles été rompues dans GCC ou je n'ai pas compris quelque chose?

+0

pouvez-vous inclure l'exemple de C++ 2003, p.30. 3.4.1, (6)? – user463035818

+0

Mieux afficher l'exemple ici même. – CinCout

+2

Si vous voulez que nous nous référions à une section particulière de la norme linguistique, il serait beaucoup plus utile si vous * citer * la partie pertinente de la norme. –

Répondre

6

Le nom à rechercher est le nom de la fonction; la règle spéciale argument-dependent lookup prend effet ici. (Notez que ADL est une partie de la unqualified name lookup pour les noms de fonction.)

Ces noms de fonction sont recherchés dans les espaces de noms de leurs arguments, en plus des champs d'application et les espaces de noms considérés par la recherche habituelle de nom non qualifié.

Au début, vous comprennent string.h, qui introduit le nom memcpy dans l'espace global. Et AA est déclaré dans l'espace de noms global; Lorsque vous appelez memcpy(&a, &a, sizeof(a));, l'espace de noms où AA est déclaré (c'est-à-dire l'espace de noms global) sera également pris en compte et le memcpy déclaré dans l'espace de noms my sera trouvé par l'unqualified name lookup habituel, l'appel est donc ambigu.

D'autre part, BB n'a pas ce problème car il n'est pas déclaré dans l'espace de noms global (et ADL ne prendra pas effet pour cela).

+0

Merci. On dirait que tu as absolument raison. Quand je lis le livre de B.Stroustroup, Le langage de programmation C++: Edition spéciale (3ème édition) (traduction russe), p.221, 8.2.6 Les noms de recherche - il a été dit "Si la fonction n'est pas trouvée dans le contexte de son utilisation, une tentative est faite pour rechercher l'espace de noms des arguments ". On dirait que comittete Standrtized a changé les règles un peu. – bruziuz

+1

@bruziuz Il pourrait être un problème de description, j'ai souvent rencontré un tel problème lors de la lecture de livre traduit; précisément, il devrait être "tous les noms trouvés par ADL et la recherche habituelle de nom non qualifié sera ajouté à l'ensemble de noms, puis la résolution de surcharge déterminera lequel doit être appelé". – songyuanyao