154/154
Projets du banc exportés par la V7 qui se recompilent tels quels dans l'IDE VB6 — mesure du 20 octobre 2026
88 s→12 s
Ouvrir un binaire de 9,35 Mo et écrire le projet complet
229→0
Procédures rendues avec un corps vide alors que la source ne l'est pas
1 129→0
Marqueurs d'erreur de structure laissés dans le code rendu
75 014→0
Signatures rendues As Unknow, faute de type

Un décompilateur ne se juge pas sur une capture d'écran. Il se juge sur ce qu'il rend quand on possède la source et qu'on peut la poser à côté.

C'est le cas ici, deux fois. SETUP1.EXE est le Setup Toolkit livré avec Visual Basic 6 : Microsoft en publie les sources, et elles sont installées sur toute machine qui a VB6. Le second témoin est un binaire de 9,35 Mo dont nous possédons le code — c'est l'ancien VBReFormer lui-même, compilé depuis ses propres sources.

Les deux produits ont ouvert ces deux fichiers et exporté le projet. Les trois versions de chaque procédure — legacy, V7 et la source d'origine — ont ensuite été appariées par composant et comparées.

Ce que « legacy » désigne exactement

La colonne legacy est celle de VBReFormer 6.4. Le build 7.1 du produit historique lève une Run-time error '91' fatale sur tout binaire contenant un formulaire — dont nos deux témoins ; il ne peut donc pas figurer dans une comparaison de sorties, puisqu'il n'en produit aucune.

La 6.4 utilisée est l'édition Free, qui masque certains noms de membres ([PROPERTY NOT VISIBLE IN FREE EDITION] : 358 occurrences sur le témoin, 99 sur SETUP1). Une Professional en règle rendrait ces noms — ce qui rapprocherait le legacy sur le seul critère des noms de membres, et ne changerait rien aux corps vides ni aux marqueurs d'erreur de structure, qui ne relèvent pas du bridage.

Ce que chaque produit écrit vraiment — témoin de 9,35 Mo

Chaque ligne est mise à l'échelle de son propre maximum : les grandeurs n'ont pas d'unité commune. La valeur exacte est écrite à droite.

legacy 6.4 VBReFormer V7 une piste vide vaut zéro
Procédures exportées1 799 vs 1 976
Corps vide alors que la source ne l’est pas229 vs 0
Marqueurs d’erreur dans le code rendu1 129 vs 0
Signatures rendues « As Unknow »75 014 vs 0
Les trois dernières lignes sont les plus lourdes de conséquence : un corps vide, un marqueur d'erreur et une signature As Unknow sont trois façons de rendre un fichier que l'IDE refusera de recompiler.

SETUP1.EXE — 238 procédures dans la source d'origine

Même échelle pour les deux barres de chaque ligne.

legacy 6.4 VBReFormer V7
Procédures écrites dans l’export (238 dans la source)136 vs 227
Lignes de code, tous fichiers (11 878 dans la source)7 464 vs 8 119
Fichiers exportés26 vs 27

Le temps

Deux mesures indépendantes, sur deux binaires de tailles très différentes.

Sur le témoin de 9,35 Mo, de l'ouverture au projet écrit sur disque : ≈ 88 s pour le legacy — dont 71 s d'analyse et une quinzaine d'écriture — contre 12 s pour la V7. Un facteur sept.

Sur SETUP1.EXE, la V7 a été instrumentée phase par phase, parce qu'un chiffre global ne dit pas ce qu'on attend. Médiane de trois passes après chauffe :

V7 sur SETUP1.EXE — où passe la seconde

227 méthodes localisées, 227 corps rendus, 6 262 lignes de source produites.

Ouvrir — format et localisation des 227 méthodes0,05 s
Décompiler les 227 corps (2,8 ms par corps)0,64 s
TypeLib, arbre et le reste du chemin produit0,26 s
De l’octet au projet complet0,95 s
Décompiler un corps coûte 2,8 ms. Le reste du temps est le format, la localisation des méthodes, les TypeLib et la construction de l'arbre.

La lecture à la main

Parce qu'un compteur ne dit pas si le code est juste.

Trente procédures ont été tirées au sort dans les sources du témoin (graine fixe, corps de 3 à 40 lignes) et douze dans celles de SETUP1, puis appariées par composant — et non par nom de fichier : cAppFile.cls ressort en ProjectContext.cls chez les deux produits, et un appariement naïf perd 41 fichiers sur 165.

Sur les trente du témoin, dix-sept sont absentes des deux (procédures de modules standard : leur nom n'est pas dans le binaire), une n'est rendue que par la V7, douze sont comparables. Avec les douze de SETUP1 : 24 procédures lues ligne à ligne contre leur source.

Le cas typique — frmGroup.LoadProgManGroups

Une boucle qui interroge le Gestionnaire de programmes par DDE, découpe la réponse et remplit une liste. Trente-trois lignes dans la source.

Source VB6 d'origine
strGroups = lblDDE.Caption
intAnchor = 1
intOffset = InStr(intAnchor, strGroups, vbCrLf)
lstGroups.Clear
Do While intOffset > 0
  strGroup = Mid(strGroups, intAnchor, _
                 intOffset - intAnchor)
  If strGroup <> strNDWGROUP Then
    lstGroups.AddItem strGroup
  End If
  intAnchor = intOffset + 2
  intOffset = InStr(intAnchor, strGroups, vbCrLf)
Loop
iGroup = SendMessageString(lstGroups.hwnd, _
         LB_FINDSTRINGEXACT, -1, mstrDefGroup)
legacy 6.4
Set var_116 = Nothing
If (-256 - 24 < 0) Then
End If
(DWORD PTR [EBP+FFFFFF48]) = -256 - 24 And 0
    …(sept fois le même bloc)
Do While (CInt(InStr(var_34, vbNullString,
                     vbCrLf, 0)) > 0)
  var_262 = Mid(vbNullString, var_34, var_num1)
  If (((var_262) <> ("Quick Access"))) Then
  …
'ERROR: Two many next close:
Loop
Call SendMessageA ()  '(API Sub call...)
VBReFormer V7
var_2C = 1
var_24 = CInt(InStr(var_2C, lblDDE.Caption, vbCrLf))
lstGroups.Clear
Do While var_24 > 0
  If StrComp(CStr(Mid(lblDDE.Caption, var_2C,
     (var_24 - var_2C))), "Quick Access") <> 0 Then
    lstGroups.AddItem CStr(Mid(lblDDE.Caption,
       var_2C, (var_24 - var_2C)))
  End If
  var_2C = (var_24 + 2)
  var_24 = CInt(InStr(var_2C, lblDDE.Caption, vbCrLf))
Loop
tmp_0 = SendMessageA(lstGroups.hWnd, 418, -1, Me.m56)

Les noms de variables locales ne sont dans aucun des deux rendus — ils ne sont pas dans le binaire, et aucun décompilateur ne peut les inventer. Ce qui sépare les deux colonnes est ailleurs : la V7 retrouve l'objet réellement lu (lblDDE.Caption), la constante strPROGMANLINKTOPIC repliée en "ProgMan|Progman", et l'appel d'API avec ses quatre arguments. Le legacy rend une chaîne vide à la place de l'objet, laisse de l'assembleur non lifté, et referme sa boucle sur un marqueur d'erreur.


Le tableau complet

Toutes les dimensions mesurées, sans sélection.

SETUP1.EXE — 286 Ko, natif, 16 composants legacy 6.4 V7 Lecture
Procédures écrites dans l'export136227238 dans la source
Procédures retrouvées sous leur nom5151égalité exacte : ce sont les gestionnaires d'événements ; les noms des procédures de module ne sont pas dans le binaire
Corps vide alors que la source ne l'est pas10
Lignes de code, tous fichiers7 4648 11911 878 dans la source
Fichiers exportés2627V7 : 26 + EXPORT-NOTES.txt
Reference= et options de compilation dans le .vbpouiouila V7 écrit Reference= pour chaque TypeLib chargée et le CompilationType ; ce que le binaire ne porte pas est consigné dans EXPORT-NOTES.txt
Témoin — 9,35 Mo, natif, 165 composants legacy 6.4 V7 Lecture
Ouverture → projet écrit≈ 88 s12 slegacy : 71 s d'analyse + ~15 s d'écriture
Procédures écrites dans l'export1 7991 9761 718 dans la source ; le binaire porte plus de méthodes (accesseurs générés)
Corps vide alors que la source ne l'est pas2290l'écart le plus large du comparatif
Lignes de code, tous fichiers54 37442 40945 165 dans la source ; le legacy gonfle par 75 014 As Unknow
Procédures dont la structuration aboutit—1 976 / 1 976aucune procédure non structurée
Fonctions du produit legacy V7
Décompilation P-codenon — module exporté videoui
Renommage global de symbolesnonoui
Références croisées, graphe d'appels, graphe de flotnonoui
Liste des symboles, signets, navigation avant/arrièreGoto seuloui
Éditeur hexadécimalpatcheur « adresse + octets »vue complète
API Browser / Object BrowserExplorateur de librairiesles deux
Notes d'export : ce qui n'a pas pu être récupéré est écritnonoui
Recherche de texte, DLL Finder, recherche de programmes, vue des ressources, export d'image, optionsouioui
Ouvre les binaires réels sans planter (build 7.1)nonoui

Le P-code

Le legacy identifie le P-code — il écrit CompilationType=-1 'P-Code dans le .vbp — puis exporte un module de 0 octet. La V7 en écrit 75 lignes, et les trois premières fonctions sont identiques à la source à la nomenclature près :

Source VB6 d'origine
Public Function Clamp(ByVal v As Integer, _
      ByVal lo As Integer, _
      ByVal hi As Integer) As Integer

    If v < lo Then
        Clamp = lo
    ElseIf v > hi Then
        Clamp = hi
    Else
        Clamp = v
    End If
End Function
VBReFormer V7 — depuis le P-code
Private Function proc_2(ByVal arg_C As Integer, _
      ByVal arg_10 As Integer, _
      ByVal arg_14 As Integer) As Integer

    If arg_C < arg_10 Then
        proc_2 = arg_10
    ElseIf arg_C > arg_14 Then
        proc_2 = arg_14
    Else
        proc_2 = arg_C
    End If
End Function

Le test qui tranche

Un export lisible ne vaut rien s'il ne se recharge pas. Alors : est-ce qu'il recompile ?

C'est le seul critère qui mesure ce qu'un client veut vraiment, et c'était jusqu'ici la seule ligne de ce document marquée « non mesurée des deux côtés ». Elle l'est maintenant.

Sur l'ensemble du banc — 154 projets exportés puis soumis à VB6.EXE /make — la V7 les fait tous recompiler : 154 / 154 au 20 octobre 2026. Le legacy n'a pas pu être soumis au même banc : il n'a pas d'export en ligne de commande, et il faudrait ouvrir les binaires un par un dans sa fenêtre.

Sur SETUP1.EXE, en revanche, le tête-à-tête a été fait. Le projet a été exporté par chacun des deux produits, puis les deux exports passés au même compilateur.

SETUP1.EXE, passé à VB6.EXE /make legacy 6.4 V7
Le projet recompilenonoui
Où VB6 s'arrête 1re ligne de code nulle part
Ce que VB6 dit Invalid character aucune erreur
Fichiers portant Attribute VB_Name (VB6 l'exige pour ouvrir un fichier) 0 / 1616 / 16
Paramètres déclarés As Unknow (ce type n'existe pas en VB6) 1 4420
Modules de 0 octet30
Noms masqués par l'édition Free99—

Seule la V7 recompile. L'export du legacy est refusé à la première ligne ; celui de la V7 passe le compilateur de bout en bout.

VB6 refuse l'export du legacy avant d'avoir lu une ligne de code : les fichiers n'ont pas d'en-tête Attribute VB_Name, et la première procédure déclare soixante et un paramètres d'un type qui n'existe pas. Le fichier n'est pas compilable parce qu'il n'est pas lisible.

L'export de la V7 est lu en entier — le formulaire, ses contrôles, puis tout le code — et SETUP1.EXE, programme Microsoft réel, recompile entier.

La précaution qui va avec

Le legacy mesuré ici est la 6.4 Free, qui masque 99 noms de membres sur SETUP1. Ce bridage aurait de toute façon empêché la compilation — mais il n'est pas la cause de l'arrêt en première ligne : celle-ci tient aux en-têtes absents et au type As Unknow, que l'édition Professional écrit de la même façon.

Et 154 / 154 reste un chiffre de la V7 seule. Le tête-à-tête ci-dessus porte sur un binaire, pas sur le banc.


Ce que nous n'avons pas mesuré

La partie d'un comparatif qui dit s'il faut le croire.

  • Le legacy Professional 7.1 sur les deux témoins. Il plante avant d'afficher quoi que ce soit.
  • Le legacy sur l'ensemble du banc de recompilation. Il y a été comparé sur SETUP1 (voir plus haut), pas sur les 154 projets : il n'a pas d'export en ligne de commande. 154 / 154 reste donc un chiffre de la V7, pas un écart.
  • Le témoin de 9,35 Mo passé au compilateur. L'export legacy du témoin n'a pas pu être obtenu : le produit attendait derrière sa fenêtre d'avertissement sur le droit d'auteur.
  • Les fonctions du legacy que nous n'avons fait qu'ouvrir (Object Browser, Explorateur de librairies, DLL Finder) : leur présence est constatée, leur qualité non.
  • L'ergonomie, la latence d'interface, la stabilité en usage prolongé.
  • Les binaires obfusqués ou protégés, absents du matériel de comparaison.

Sur les deux binaires réels, la V7 rend un code substantiellement plus fidèle que le legacy, à parité de noms retrouvés — et elle le fait sept fois plus vite. Et le projet qu'elle écrit se recompile : 154 projets sur 154 au banc, SETUP1.EXE compris.

Méthode. Les deux produits ont été exécutés sur les mêmes fichiers, leurs exports appariés par composant, et chaque procédure comparée à la source VB6 d'origine (…/PDWizard/Setup1/*.FRM,*.BAS et les sources de l'ancien produit). Les temps V7 sont des médianes de trois passes après chauffe. Aucune ligne de moteur n'a été modifiée entre la mesure et la publication. Mesures du 5 septembre 2026 ; la recompilation (banc et SETUP1.EXE) a été mise à jour le 25 octobre 2026.

Un chiffre de cette page qui ne serait pas reproductible est un défaut de la page.