2017-07-11 1 views
2

J'utilise Visual Studio 2015 Update 3.Visual Studio offre une couverture de code partielle pour les nouveaux initialiseurs

Je suis à défaut d'obtenir une couverture de code 100% sur ce Unit Test simple:

TEST_METHOD(New) 
{ 
    int* test = new int(4); //shows the line as partially covered 
    int* test2 = new int; //shows line as 100% covered 
} 

Cela se produit si les déclarations sont dans le code appelé par la fonction de test ainsi.

Le seul paramètre modifié par défaut pour le projet est le commutateur /profile, qui est nécessaire pour que toute couverture de code fonctionne en premier lieu.

je remarquai que new lorsqu'il est utilisé sans initializer montre la couverture 100%, mais pour les classes que je les initialize habituellement tout de suite et je voudrais trouver un moyen de le faire sans réduire la couverture de code.

Code de désassemblage

   int* test = new int(4); //shows the line as partially covered 
0F951D53 push  4 
0F951D55 call  operator new (0F9512B2h) 
0F951D5A add   esp,4 
0F951D5D mov   dword ptr [ebp-0ECh],eax 
0F951D63 cmp   dword ptr [ebp-0ECh],0 
0F951D6A je   UnitTest1::UnitTest1::New+56h (0F951D86h) 
0F951D6C mov   eax,dword ptr [ebp-0ECh] 
0F951D72 mov   dword ptr [eax],4 
0F951D78 mov   ecx,dword ptr [ebp-0ECh] 
0F951D7E mov   dword ptr [ebp-100h],ecx 
0F951D84 jmp   UnitTest1::UnitTest1::New+60h (0F951D90h) 
0F951D86 mov   dword ptr [ebp-100h],0 
0F951D90 mov   edx,dword ptr [ebp-100h] 
0F951D96 mov   dword ptr [test],edx 
      int* test2 = new int; //shows line as 100% covered 
0F951D99 push  4 
0F951D9B call  operator new (0F9512B2h) 
0F951DA0 add   esp,4 
0F951DA3 mov   dword ptr [ebp-0F8h],eax 
0F951DA9 mov   eax,dword ptr [ebp-0F8h] 
0F951DAF mov   dword ptr [test2],eax 

En regardant le code, je devine les jmp déclarations provoquent l'outil d'analyse de couverture de code pour voir quelques déclarations de ne pas frapper.

+0

Ignorer les commentaires précédents J'avais confondu "nouveau avec l'initialiseur", et "nouveau tableau"! –

+0

Essayez de regarder l'assemblage et voir s'il y a des sauts inattendus ou quelque chose du genre –

+0

@MartinBonner I Je l'ai juste ajouté, je soupçonne que l'un des deux sauts pourrait être la cause, mais je n'ai aucune idée de la façon de le réparer – meneldal

Répondre

2

Vous semblez avoir une option qui signifie que new se comporte toujours comme new(nothrow) (en d'autres termes, new renvoie nullptr si l'allocation échoue).

L'assembly vérifie si operator new a retourné nullptr (et si c'est le cas, ne pas stocker 4 à l'adresse retournée). Vous devez tester le cas où l'allocation a échoué afin d'avoir une couverture complète. En C++, l'ensemble ressemble à:

int * test; 
    int * tmp = operator new(sizeof(int)); 
    if (tmp != nullptr) { 
     *tmp = 4; 
     test = tmp; 
    } else { 
     test = nullptr; 
    } 

Modifier

Ah ha! Dans this blog post Microsoft expliquent que le code généré pour nouveau a testé un retour null, juste au cas où vous liez dans la nothrow version. Avec VC2015, ils ont fourni une option pour dire « ne prennent pas la peine de faire cela, new jetteront, il ne reviendra jamais nullptr

Ainsi, pour éviter la branche inutile, ajouter:.. /Zc:throwingNew les options de compilation (Cette

+0

Donc, il n'y a pas de façon concise de le marquer comme entièrement couvert? Je teste déjà le cas où ' nullptr' est envoyé aux fonctions que j'utilise quand même. – meneldal

+0

Merci, j'ai cherché sur le site de Microsoft, mais je n'ai pas trouvé cela, votre Google-fu est à un niveau différent. Accepté votre réponse. – meneldal