OVH Cloud OVH Cloud

Question sur la compilation

58 réponses
Avatar
Michaël Delva
Bonjour à tous,

j'ai une petite question sur la compilation:

J'ai un fichier .H où sont déclarées 3 fonctions A, B et C, et le .CPP où
se trouvent leurs implémentations.

J'ajoute le .CPP au projet, et dans le code du projet je n'utilise pas la
fonction C.

Quel est le comportement du compilateur: est-ce que la fonction C est quand
même incluse dans l'EXE?

Je me pose la question car avec mon compilo (Borland 6) quand je suis en
mode debug je ne peux pas ajouter de points d'arrets sur le code des
fonctions ou classes que je n'utilise pas.

Et enfin (plus spécifique Windows), est-ce le même principe pour les DLLs?
(Mais pourquoi ne serait-ce pas le cas?)

Merci d'avance...

10 réponses

2 3 4 5 6
Avatar
Christophe de VIENNE
James Kanze writes:


Tu as des mésures ? J'en ai pas avec C++, mais dans la passé, avec un
compilateur C, sans optimisation, la tokenisation représentait environ
40% du temps CPU total. Sans parler du fait que faire avec deux
processus séparés, ça veut dire passer les données par le disque, avec
des lectures et des écritures en plus.



Mini benchmark avec gcc sur un "hello, world" (donc, en gros, on
compile stdio.h ...)
0,01 sec pour le préprocesseur
0,03 sec pour la compilation (-> assembleur)
0,10 sec pour la compilation + assemblage (-> fichier objet).
0,60 sec pour la compilation complete (-> executable).

Dans ce ca là en tous cas, le préprocesseur est bien négligeable
devant le reste de la compil. Mais je ne sais pas à quel point c'est
représentatif ...




J'ai fait un test avec un des fichiers de mon projet qui instancie
quelque fonctions templates, et implémente quelques classes, et du coup
c'est la compilation la plus longue (g++ 3.3.3) :

Préprocessing seulement: 0.3s
Préprocessing + compilation: 5.7s
Préprocessing + compilation + assemblage: 6.4s

Ce qui explique pourquoi distcc est efficasse avec mon projet : même si
le préprocessing est fait systématiquement en local, c'est la
compilation + assemblage qui est le plus gourmand en CPU.



--
Christophe de Vienne


Avatar
Gabriel Dos Reis
writes:

| Je suis en effet intrigué du fait que dans la génération de l'objet,
| c'est l'assembleur qui prend le plus de temps. Ça fait bien penser qu'un

Génération de fichier .s sur disk, tokenisation séparée de .s,
génération de .o + linking.

| des aspects critiques, c'est les temps de lecture -- c'est bien
| l'assembleur qui lit les plus de données. Est-ce que ce serait encore le
| cas que même avec un langage aussi compliqué que le C++, c'est les
| entrées/sorties qui prédomine ?

Avec des programmes C++ typiques, souvent je vois

* name lookup
* overloading resolution
* template instantiation
* optimization (s'il y en a).

-- Gaby
Avatar
Gabriel Dos Reis
Christophe de VIENNE writes:

| > James Kanze writes:
| >
| >>Tu as des mésures ? J'en ai pas avec C++, mais dans la passé, avec un
| >>compilateur C, sans optimisation, la tokenisation représentait environ
| >>40% du temps CPU total. Sans parler du fait que faire avec deux
| >>processus séparés, ça veut dire passer les données par le disque, avec
| >>des lectures et des écritures en plus.
| > Mini benchmark avec gcc sur un "hello, world" (donc, en gros,
| > on
| > compile stdio.h ...)
| > 0,01 sec pour le préprocesseur
| > 0,03 sec pour la compilation (-> assembleur)
| > 0,10 sec pour la compilation + assemblage (-> fichier objet).
| > 0,60 sec pour la compilation complete (-> executable).
| >
| > Dans ce ca là en tous cas, le préprocesseur est bien négligeable
| > devant le reste de la compil. Mais je ne sais pas à quel point c'est
| > représentatif ...
| >
|
|
| J'ai fait un test avec un des fichiers de mon projet qui instancie
| quelque fonctions templates, et implémente quelques classes, et du
| coup c'est la compilation la plus longue (g++ 3.3.3) :

Pour GCC-3.x, je ne suis pas du tout surpris.

| Préprocessing seulement: 0.3s
| Préprocessing + compilation: 5.7s
| Préprocessing + compilation + assemblage: 6.4s

-- Gaby
Avatar
Michel Michaud
Dans news:,
Pierre Maurette wrote in message
news:...
typa:
Je croyais qu'on disait « éditeur de liens » en français.
Quand on ne dit pas carrément « linker »:-).


Tiens, c'est marrant, Microsoft est 100% "Editeur de liens",
Borland 100% "Lieur". Je n'avais pas remarqué.


Intéressant. C'est la première fois que j'entends « lieur ».


Moi aussi. Et ça fait certainement plus de 20-25 ans que c'est
la traduction que je vois partout. C'est aussi celle indiquée,
la seule, dans mes deux dictionnaires d'informatique.

Probablement que c'est Borland qui n'a pas vraiment de linker
dans leur système :-)

Peut-être le mieux alors, c'est « linker ». Au moins comme ça,
on est sûr que tout le monde nous comprend:-).


Non, le mieux est « éditeur de liens ». Comme ça, on parle
français et on utilise la bonne traduction...

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/



Avatar
Loïc Joly
wrote:

Loïc Joly wrote in message
news:<c9o225$sif$...

James Kanze wrote:



|> Je n'apprécie en particulier pas qu'un même fichier objet inclus
|> directement ou par l'intermédiaire d'une bibliothèque puisse
|> produire des exécutables aux comportements différents.




Est-ce que tu en as un exemple où c'est le cas ?



[...]



Avec Visual C++ 6, la variable globale dummy existe bien quand on lie
l'objet directement, mais pas quand MyObject est dans une
bibliothèque.



Et qu'est-ce que tu as fait pour dire à VC++ que MyObject fasse partie
de ton programme ? Si tu ne lui as pas dit que MyObject.cpp (ou l'objet
qui en sort) fasse partie de ton programme, c'est normal que le
compilateur ne le prend pas en compte.


Je lui ai dit que l'objet faisait partie de la bibliothèque et que la
bibliothèque faisait partie de programme. En l'absence de définition
plus précise de ce que "faire partie" et "bibliothèque" veulent dire (et
je reporoche justement au standard de ne pas en donner), la conclusion
la plus directe est que l'objet est inclus dans le programme.

Je vais reciter le fameux paragraphe de la norme, dans son entier :

All external object and function references are resolved. Library
components are linked to satisfy external references to functions and
objects not defined in the current translation. All such translator
output is collected into a program image which contains information
needed for execution in its execution environment.


All external object and function references included directly (i.e.: not
from a library) are resolved...

[...]

Je ne dis pas le contraire. Mais enfin, je ne comprends pas où tu veux
en venir. On est parti de ce qu'exige, ou de ce que devait exiger, la
norme. Tu n'aimes pas la syntaxe que fournit VC++ pour préciser qu'une
unité de compilation spécifique fasse partie de ton programme. Alors,
est-ce que tu veux que la norme précise la syntaxe nécessaire pour
invoquer les commandes de compilation ?


Non, je souhaiterait qu'elle définisse le mot si couramment utilisé de
"library", et en particulier, si les unités de compilations inclues par
l'intermédiaire d'une bibliothèque ont un statut particulier par rapport
à celles inclues directement.

Je suppose que la norme pourrait être plus clair, mais à mon avis,
l'intention est claire, §2.1/9 : « Library components are linked to
satisfy external references to functions and objects not defined in the
current translation. » Autant que je vois, MyObject.cpp ne contient pas
de symbole qui correspond à un « external references functions and
objects not defined in the current translation ».


MyObject.cpp fait référence au symbole Factory::instance.


Ça serait donc une
erreur de l'incorporer s'il fasse partie d'une bibliothèque, *au*
*moins*


Pour info (je t'ai vu faire ce contresens plusieurs fois), "au moins"
correspond à "at least", et ce qui correspond à "unless" est "à moins"
(suivi du subjonctif). Ah, les pièges du français...

qu'on a dit explicitement au compilateur qu'on le veut. VC++ est
conforme à cet égard. De même que tout autre compilateur dont je me suis
servi. Depuis plus de trente ans. C'est la définition classique de
comment un éditeur de liens traite une bibliothèque.


Elle est peut-être classique, mais je ne vois rien dans la norme qui
l'explicite.


Et je répète : dans ce cas-ci, le comportement de ton programme n'a pas
changé selon qu'un objet se trouve dans une bibliothèque ou non. Le
comportement a changé du fait que tu as changé l'ensemble des objets
dans le programme.


Je me cite :
Je n'apprécie en particulier pas qu'un même fichier objet inclus
directement ou par l'intermédiaire d'une bibliothèque puisse
produire des exécutables aux comportements différents.


Que retrouves-tu à dire à cette phrase ?

--
Loïc



Avatar
Loïc Joly
Jean-Marc Bourguet wrote:

Loïc Joly writes:


A moins que ce soit ma lecture du standardese qui soit déficiente,
"Library components are linked to satisfy external references to
functions and objects not defined in the current translation." me
semble un peu vague.



J'ai toujours compris ce "Library" comme faisant reference a la
bibliotheque standard.


Tiens, intéressant. Si c'est le cas, le concept de bibliothèque
utilisateur n'est plus seulement très vaguement défini par la norme,
mais il lui est totalement étranger.

D'autres avis là dessus ?

--
Loïc


Avatar
kanze
Loïc Joly wrote in message
news:<c9vsqj$ild$...
wrote:

Loïc Joly wrote in message
news:<c9o225$sif$...

James Kanze wrote:

|> Je n'apprécie en particulier pas qu'un même fichier objet
|> inclus directement ou par l'intermédiaire d'une bibliothèque
|> puisse produire des exécutables aux comportements différents.

Est-ce que tu en as un exemple où c'est le cas ?




[...]

Avec Visual C++ 6, la variable globale dummy existe bien quand on
lie l'objet directement, mais pas quand MyObject est dans une
bibliothèque.


Et qu'est-ce que tu as fait pour dire à VC++ que MyObject fasse
partie de ton programme ? Si tu ne lui as pas dit que MyObject.cpp
(ou l'objet qui en sort) fasse partie de ton programme, c'est normal
que le compilateur ne le prend pas en compte.


Je lui ai dit que l'objet faisait partie de la bibliothèque et que la
bibliothèque faisait partie de programme.


Une bibliothèque ne peut pas faire partie d'un programme. Un programme
est un assemblage des objets. Une bibliothèque est une collection
d'objets, normalement gérée d'une façon particulière.

J'ai déjà utilisé un éditeur de liens qui avait une commande pour dire
que tous les objets dans une bibliothèque fasse partie du programme.
Mais c'est une exception -- je ne connais pas de telle commande avec les
éditeurs de liens Unix, et encore moins pour ceux de Windows.

En l'absence de définition plus précise de ce que "faire partie" et
"bibliothèque" veulent dire (et je reporoche justement au standard de
ne pas en donner), la conclusion la plus directe est que l'objet est
inclus dans le programme.


D'abord, la norme n'en est pas entièrement silencieuse. Mais plus
généralement, ça fait partie de la définition de « objet » et de
«@bibliothèque ». Une bibliothèque, c'est une collection d'objets d'où
l'éditeur de liens tirent les objets nécessaires, et que les objets
nécessaires.

Je m'étonne un peu que tu aies un problème ici. Si c'était quelqu'un
d'autre, je dirais que ça fait partie du b a ba de la compilation, et
qu'il aurait dû l'apprendre dans le premier cour du langage. Or, je sais
que tu as largement dépassé ce niveau.

Je vais reciter le fameux paragraphe de la norme, dans son entier :

All external object and function references are resolved. Library
components are linked to satisfy external references to functions and
objects not defined in the current translation. All such translator
output is collected into a program image which contains information
needed for execution in its execution environment.


All external object and function references included directly (i.e.:
not from a library) are resolved...


Non, parce qu'on résoud aussi les références des objets inclus depuis
une bibliothèque. Ce qui est claire, c'est que les « library components
are linked to satisfy external references to funcitons and objects not
defined in the current translation. » C-à-d qu'un système qui incorpore
tous les objets d'une bibliothèque, sans poser de question, ne serait
pas conforme. (Sauf, évidemment, qu'il suffirait de dire que ce qu'elle
appelle une bibliothèque n'en est pas une au sens de la norme. C'est le
cas des DLL, par exemple.)

La phrase pourrait être plus claire : il faudrait dire que ces
inclusions sont transitives, c-à-d que les symboles externes non
résolus introduits par un composant extrait d'une bibliothèque sont pris
en considération par la suite (mais c'est difficile à formuler d'une
façon qui convient à toutes les variations dans le fonctionnement des
bibliothèques). Il faudrait aussi éventuellement dire qu'on incorpore
aussi des « instantiation units » impliqués par les composants qu'on
incorpore d'une bibliothèque.

[...]

Je ne dis pas le contraire. Mais enfin, je ne comprends pas où tu
veux en venir. On est parti de ce qu'exige, ou de ce que devait
exiger, la norme. Tu n'aimes pas la syntaxe que fournit VC++ pour
préciser qu'une unité de compilation spécifique fasse partie de ton
programme. Alors, est-ce que tu veux que la norme précise la syntaxe
nécessaire pour invoquer les commandes de compilation ?


Non, je souhaiterait qu'elle définisse le mot si couramment utilisé de
"library",


Et pourquoi pas « program », et « source », et « translate », et ...

C'est un mot dans le vocabulaire de base de l'informatique. C'est une
collections d'autres fichiers. Une bibliothèque n'est pas un composant,
c'est une collection de composants. Dont on linke les composants
nécessaires pour satisfaire les références externes non définies. Selon
la norme.

et en particulier, si les unités de compilations inclues par
l'intermédiaire d'une bibliothèque ont un statut particulier par
rapport à celles inclues directement.


Dans la mésure que la norme ne dit pas autrement, j'aurais tendance à
dire que les unités de compilation inclues depuis une bibliothèque se
comportent exactement comme les autres unités de compilation. Je suis
d'accord que la norme pourrait être plus claire à ce sujet ; je serais
très embêté si par exemple la phase 8 (instantiation des templates) ne
se faisait pas sur ces unités. Mais je ne le vois pas comme un grand
problème ; je crois que tout le monde est d'accord sur ce qu'une
implémentation doit faire, et en tout cas, je n'ai jamais entendu parler
d'une implémentation qui les traitait différemment.

Reste que ça ne résoud pas ton problème : parce que selon la norme même,
on ne doit inclure des unités de compilations (des composants) de la
bibliothèque que si elles satisfont une référence externe à une fonction
ou à un objet qui n'est pas définie dans le programme autrement.

Je suppose que la norme pourrait être plus clair, mais à mon avis,
l'intention est claire, §2.1/9 : « Library components are linked to
satisfy external references to functions and objects not defined in
the current translation. » Autant que je vois, MyObject.cpp ne
contient pas de symbole qui correspond à un « external references
functions and objects not defined in the current translation ».


MyObject.cpp fait référence au symbole Factory::instance.


Alors, si MyObject.cpp (ou l'objet qui en résulte) est incorporé dans le
programme, et que Factory::instance n'est pas aurement défini, mais est
défini dans une bibliothèque, il faudrait incorporer l'unité de
traduction qui le comprend dans le programme.

Dans ton exemple, il s'agissait plutôt d'une unité de traduction qui ne
comportait que deux symboles : createMyObject et dummy. Et, au moins tel
que je l'ai compris, il n'y avait pas de référence ni à l'un ni à
l'autre de ces symboles ailleurs.

Ça serait donc une erreur de l'incorporer s'il fasse partie d'une
bibliothèque, *au* *moins*


Pour info (je t'ai vu faire ce contresens plusieurs fois), "au moins"
correspond à "at least", et ce qui correspond à "unless" est "à moins"
(suivi du subjonctif). Ah, les pièges du français...


Merci. (C'est comme ça que j'apprends.)

qu'on a dit explicitement au compilateur qu'on le veut. VC++ est
conforme à cet égard. De même que tout autre compilateur dont je me
suis servi. Depuis plus de trente ans. C'est la définition classique
de comment un éditeur de liens traite une bibliothèque.


Elle est peut-être classique, mais je ne vois rien dans la norme qui
l'explicite.


C'est fortement suggéré par le passage que j'ai cité. Sans doute la
norme n'en est pas plus précise parce que 1) on n'en voyait pas la
nécessité, étant donné que c'est la définition générale, et 2) c'est
très difficile à préciser plus sans préciser trop en ce qui concerne le
fonctionnement des éditeurs de liens. En ce qui concerne les
bibliothèques, j'en connais au moins trois variantes :

- L'éditeur de liens incorpore tous les objets d'abord. Puis, il
cherche les bibliothèques pour résoudre les externes non résolues,
récursivement sur toutes les bibliothèques. C'est le comportement
usuel sous Windows.

- L'éditeur de liens traite les fichiers dans l'ordre qu'on les
spécifie. Si le fichier est une bibliothèque, il le cherche
récursivement pour résoudre les externes non-résolues jusqu'alors,
dans les modules déjà incorporées. En revanche, il ne le cherche
jamais pour des externes dans les fichiers qui le suit. C'est le
comportement usuel sous Unix.

- Comme ci-dessus, sauf que l'éditeur de liens ne fait qu'une passe
sur la bibliothèque, en considérant chaque fichier qu'il contient
dans l'ordre. C'était le cas avec quelques éditeurs de liens
primitifs dont je me suis servi au début de ma carrière (à une
époque où il était encore courant de garder des fichiers objet et
des bibliothèques sur bande magnétique).

Et je répète : dans ce cas-ci, le comportement de ton programme n'a
pas changé selon qu'un objet se trouve dans une bibliothèque ou non.
Le comportement a changé du fait que tu as changé l'ensemble des
objets dans le programme.


Je me cite :
Je n'apprécie en particulier pas qu'un même fichier objet inclus
directement ou par l'intermédiaire d'une bibliothèque puisse
produire des exécutables aux comportements différents.


Que retrouves-tu à dire à cette phrase ?


Que le seul exemple que tu as pu présenté, c'est que tu inclus l'objet
dans un cas, et que tu ne l'inclus pas dans l'autre. Et que c'est un
comportement qui me semble on ne peut plus normal. Je ne vois pas
comment tu veux que l'implémentation fasse quoique ce soit avec un
composant qui ne fasse pas partie de ton programme. Et je ne vois pas
non plus comment l'implémentation peut déviner que tel ou tel objet doit
faire partie de ton programme si tu ne lui le dit pas explicitement, ou
s'il n'y a pas une référence dans un objet qui en fait partie pour lui
le dire.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34




Avatar
kanze
"Michel Michaud" wrote in message
news:<C82wc.120883$...

Peut-être le mieux alors, c'est « linker ». Au moins comme ça, on
est sûr que tout le monde nous comprend:-).


Non, le mieux est « éditeur de liens ». Comme ça, on parle français et
on utilise la bonne traduction...


Et « faire une édition de liens », ou « éditer des liens », plutôt que
« linker » ?

Je suis d'accord pour parler français, mais ça devient un peu lourd à la
longue, tu ne trouves pas ? (En revanche, on n'a pas le problème qu'en
français, « linker » substantif se prononce différemment de « linker »
infinitif du verbe.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Jean-Marc Bourguet
writes:

"Michel Michaud" wrote in message
news:<C82wc.120883$...

Peut-être le mieux alors, c'est « linker ». Au moins comme ça, on
est sûr que tout le monde nous comprend:-).


Non, le mieux est « éditeur de liens ». Comme ça, on parle français et
on utilise la bonne traduction...


Et « faire une édition de liens », ou « éditer des liens », plutôt que
« linker » ?


J'utilise « lier » quand j'essaie d'eviter « linker », ce qui ne
m'arrive pas tres souvent.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
kanze
Loïc Joly wrote in message
news:<c9vsuo$6jr$...
Jean-Marc Bourguet wrote:

Loïc Joly writes:

A moins que ce soit ma lecture du standardese qui soit déficiente,
"Library components are linked to satisfy external references to
functions and objects not defined in the current translation." me
semble un peu vague.


J'ai toujours compris ce "Library" comme faisant reference a la
bibliotheque standard.


Tiens, intéressant. Si c'est le cas, le concept de bibliothèque
utilisateur n'est plus seulement très vaguement défini par la norme,
mais il lui est totalement étranger.

D'autres avis là dessus ?


C'est que c'est loin d'être clair, et que l'interprétation de Jean-Marc
est tout à fait possible.

En général, la norme ne dit rien, exprès, sur les modalités de piloter
l'implémentation : comment invoquer le compilateur ou ces différentes
phases, comment préciser les noms des sources, ou plus généralement
quels objets font partie du programme, etc. Je ne crois pas qu'une
implémentation soit obligée à fournir un moyen aux utilisateurs de créer
leurs propres bibliothèques. (En fait, une implémentation n'est même pas
obligée à supporter la compilation séparée ; il peut très bien exiger
que tu donnes les noms de tous les sources dans une seule commande.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



2 3 4 5 6