2010-11-07 5 views
2

J'ai un fichier programme C++ avec deux fonctions. Si je change seul la première fonction, pourquoi les deux devraient-ils être recompilés? Existe-t-il un système de compilation qui recompile le premier seul et le remet dans le même fichier objet? Est-ce possible? Les instructions d'une fonction ne devraient pas dépendre d'un autre droit? Depuis gmake recompile le fichier entier, cela prend beaucoup de temps, ne peut pas être évité? Mettre la deuxième fonction dans un fichier séparé n'est pas une bonne idée, car cela implique la création de fichiers indésirables, ce qui n'est pas nécessaire.Alternatives pour gmake?

Répondre

4

L'analyse visant à déterminer quelles parties sémantiques d'un fichier source donné ont changé et doivent donc être recompilées l'emporterait probablement sur le coût de la compilation elle-même dans la plupart des cas.

Les systèmes de construction obtiennent de gros gains en analysant les dépendances entre les fichiers sources car le coût des E/S de fichiers (en particulier pour les fichiers d'inclusion) représente une grande partie du coût global de la compilation. Une fois que vous avez décidé de recompiler un fichier source donné, vous n'obtiendrez vraisemblablement qu'une petite accélération en ignorant les parties inchangées du fichier, même si le coût de ces pièces était nul.

+0

L'accélération est-elle très minuscule même si les autres fonctions impliquent l'utilisation de nombreux modèles? – balki

6

Si la deuxième fonction est assez longue ou requiert plus de temps pour la compilation, placez-la dans un fichier séparé. C'est pourquoi les gens séparent les fichiers source. D'après ce que je sais, il doit compiler le fichier entier, car un petit changement dans la source entraînera un changement majeur dans le fichier de sortie, car les fonctions ne se lieraient pas les unes aux autres.

0

Le problème n'est pas gmake, c'est le compilateur. Si vous changez une fonction, vous n'aurez pas d'autre choix que de recompiler les autres. Par exemple:

  • si la fonction a appels fonction b, et que vous modifiez la fonction b, vous devez vous assurer que le a appelle encore b correctement, dans la signature de cas b changé.
  • si la fonction est b entre a et c dans la mémoire, et maintenant b grandit de sorte qu'il ne correspond plus à, vous pouvez avoir à se déplacer soit a ou c, ce qui implique également recompiler pour générer des décalages corrects. Si b n'est plus au même endroit, vous devez compiler son appelant, a pour pointer vers la bonne fonction.

Il y a probablement des cas plus nombreux et meilleurs où cela est nécessaire.

+0

Le premier point est vrai du compilateur, et est résolu en mettant la définition de la fonction dans un fichier d'en-tête partagé. Les deux seconds sont des points pour le lieur, pas pour le compilateur - changer l'implémentation (mais pas la définition) d'une fonction en C++ nécessite que les artefacts dépendants soient reliés, pas recompilés. –

5

Je doute que la compilation d'une partie seulement d'un fichier source soit possible, en utilisant n'importe quel langage de programmation. Les compilations sont effectuées par fichier.

+0

AFAIK, ces langages qui résolvent la compilation au niveau de la fonction le résolvent en ne se basant pas sur des fichiers source, mais sur des représentations plus puissantes (par exemple Smalltalk). –

+0

À l'instar de ce que Pete a dit, je pense que le compilateur IBM VisualAge C++ le faisait. Je ne l'ai jamais utilisé si je ne peux pas dire à coup sûr. –

1

Tous les systèmes de construction pour C++ que je connais travaillent au niveau de l'unité de traduction (fichier), pas au niveau de la fonction. Bien qu'en théorie cela devrait être possible, c'est compliqué quand vous considérez le préprocesseur, par ex.

#define ANSWER 42 

void foo() 
{ 
#undef ANSWER 
#define ANSWER 41 
} 

int bar() 
{ 
    return ANSWER; 
} 

Bien que ce soit un code terrible, tout compilateur/système de compilation conforme standard devrait le supporter. Et comme vous pouvez le voir changer foo (redéfinir ANSWER) peut affecter bar.

+0

Probablement pas un exemple juste, car les directives du préprocesseur vivent à une phase antérieure de compilation que les définitions de fonction. C'est-à-dire que votre redéfinition de ANSWER ne fait pas vraiment partie de la fonction foo(), même si elle ressemble à ça. En y réfléchissant, c'était probablement exactement ce que vous vouliez dire ... –

1

Mettre la deuxième fonction dans un fichier séparé est une bonne idée, et est nécessaire si vous voulez éviter ce « problème ». Si vos fonctions sont si grandes que le temps passé à recompiler un fichier est notable, alors le fichier est probablement trop gros et devrait être brisé de toute façon.