7

J'ai rencontré un symptôme très étrange. Qui peut me dire quelle est la cause première?Pourquoi le compilateur VC++ 2010 plante-t-il lors de la compilation de code simple?

version du compilateur de mon CV est le dernier: "Microsoft Visual C++ 2010: 01019-532-2002102-70860"

Procédure pour reproduire:

  1. Créer un projet console win32 vide
  2. Ajouter un nouveau fichier cpp nommé main.cpp
  3. Collez le code suivant dans main.cpp
  4. Compile
  5. Les accidents du compilateur et des rapports le message suivant:

\ bug \ main.cpp (54893757): erreur fatale C1001 : Une erreur interne est survenue dans le compilateur. (Fichier compilateur « de msc1.cpp », ligne 1420)

Pour contourner ce problème, essayez simplifier ou modifier le programme près des endroits indiqués ci-dessus. Veuillez sélectionner la commande Support technique dans le menu Aide de Visual C++, ou ouvrez le fichier d'aide du support technique pour plus d'informations.

Cette erreur est survenue dans le texte injecté:

d: \ bug \ main.cpp (63): voir référence à la fonction modèle instanciation 'XDummy test (T)' étant compilé avec [ T = int ]

Échec de construction.

est en dessous du code source de main.cpp:

#include <vector> 

template<class It_> 
struct trait_dummy 
{ 
    static const int value = std::tr1::is_convertible<typename iterator_traits<It_>::iterator_category, int>::value;  
}; 

template<class It_> 
class X 
{ 
public: 
    template<class T_> 
    X(T_& rColl) 
    {} 
}; 

template<class T_> 
X<typename T_::iterator> f(T_ rColl, std::false_type) 
{ 
    return X<typename T_::iterator>(rColl); 
} 

template<class T_> 
auto f(T_& rColl) -> decltype(f(rColl, std::false_type())) 
{ 
    return f(rColl, std::false_type()); 
} 

template<class It_> 
X<It_> f(It_ first, size_t nSize, typename std::tr1::enable_if<trait_dummy<It_>::value>::type* dummy = 0) 
{ 
    return X<It_>(first, first + nSize); 
} 

class XTest 
{ 
public: 
    void foo() 
    { 
     auto v = f(m_Suite); 
    }  

    std::vector<int> m_Suite; 
}; 

const int g_dummy = 0; 
class XDummy 
{ 
public: 
    XDummy(int, int, int, int dummy = g_dummy) 
    {} 
}; 

template<class T> 
XDummy Test(T) 
{  
    return XDummy(0, 0, 0); 
} 

int main() 
{ 
    Test(0); 
    //XTest().foo(); 

    return 0; 
} 
+2

Si vous pouvez réduire votre code au code minimum qui provoque l'erreur interne du compilateur, veuillez envoyer un rapport de bogue sur [Microsoft Connect] (http://connect.microsoft.com/). –

+0

Utiliser le mot-clé auto comme ça semble mauvais/paresseux. Je ne veux pas avoir à explorer plusieurs couches d'appel de fonction pour savoir quel type renvoie une fonction. Et si le type de retour d'une fonction interne change, je préférerais avoir des erreurs de compilateur au moment où la fonction modifiée a été appelée plutôt que deux couches, se demandant ce qui s'est passé et ayant à chercher la cause de la modification (s)) ... L'utilisation de l'auto est pratique lors de la définition des variables locales de l'itérateur, mais l'utiliser dans les signatures de fonctions semble être une mauvaise idée. –

+0

@Leo Davidson: Je n'aime pas auto + decltype aussi. Cependant, dans de nombreux cas, auto + decltype est indispensable. Si ce n'est pas nécessaire, je ne les utiliserai pas pour définir une fonction. – xmllmx

Répondre

5

Avez-vous essayé tout type de vous dépanner?

Je peux reproduire le plantage en utilisant le code source ci-dessus que vous décrivez. Bien sûr, je reçois quelques avertissements:

  • "IntelliSense: aucune instance de fonction surchargée "f" correspond à la liste des arguments"
  • "IntelliSense: trop peu d'arguments en appel de la fonction"

à la fois référence à cette ligne:

auto v = f(m_Suite); 

quelques secondes de dépannage découvre que en commentant l'ensemble de la classe XTest, le code compile et ex ecutes sans problème (et surtout, sans écraser le compilateur). Cela me dit (et devrait vous dire) que le problème se situe clairement quelque part dans la classe XTest.
Vous ne pouvez pas vous empêcher de vous demander si cela a quelque chose à voir avec les erreurs du compilateur qui sont générées. Eh bien, que diriez-vous si nous nous contentons de commenter cette seule ligne qui produit les erreurs du compilateur? Qu'est-ce que tu sais! Le code compile et s'exécute très bien!

Donc en moins d'une minute, nous avons réduit le coupable à une seule ligne de code. Je ne vais pas prendre le temps de comprendre exactement ce que tout votre code fait, car je pense que vous pouvez le prendre d'ici maintenant que vous savez exactement où concentrer vos efforts. Commencez par corriger ces erreurs IntelliSense et vérifiez si votre code compile sans écraser le compilateur.

+1

Notez que les erreurs "IntelliSense ..." ne sont pas vraiment des erreurs de compilation car elles sont générées par IntelliSense, pas par le compilateur. Le compilateur Visual C++ et IntelliSense utilisent des interfaces complètement différentes, si souvent que l'un peut signaler une erreur tandis que l'autre ne peut pas. –

+3

IMO chose drôle au sujet de compilateur de code invalide écrasant n'est pas que le code est invalide, mais qu'il plante le compilateur :) –

+1

@James McNellis: Vous avez raison qu'ils ne sont pas strictement des erreurs de compilation, mais les avertissements me semblent indiquer Quelque chose pourrait mal se passer avec cette ligne de code, et de mes tests, c'est le cas. Cela devrait au moins les rendre dignes d'attention, compte tenu des circonstances. –

0

Les auteurs de compilateurs n'accordent pas une très haute priorité à la correction des bogues dans leur compilateur qui n'affectent pas la capacité du compilateur à générer une sortie valide à partir d'une entrée valide. Et parmi ces bogues, la priorité la plus basse va aux bogues qui ne produisent pas de sortie non valide.

Donc, la réponse à votre question est que c'est probablement parce que ce bug n'a pas été signalé précédemment ou a reçu une très, très faible priorité.