Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

une histoire de fou, linkers qui pètent les plombs

10 réponses
Avatar
Alain Cabiran
Bonjour,

j'ai un gros pb avec les liaisons, j'ai testé avec g++ 2.95 g++ 3.0
g++ 3.3 et c++ builder :

si je groupe tout le code dans le même fichier, pas de problème

si je sépare en 2 cpp et un h, j'ai une référence indéfinie à la liaison
vers insert et erase quand je compile le tout.,

quelqu'un y comprend qqch ?

merci d'avance,

Alain Cabiran



voilà le code :

idlist.h
----------------
#ifndef IDSORTEDLIST_H
#define IDSORTEDLIST_H

#include <list>

template <class T> class IdSortedList {
public:
typedef std::list<T> idList; // déf. iter. plus courtes
typedef typename idList::iterator iterator;
typedef typename idList::reverse_iterator reverse_iterator;

IdSortedList() { } ;
virtual ~IdSortedList() { } ;

virtual iterator insert(const T &);
virtual bool erase(double);

protected:
std::list<T> data;
};
#endif


idlist.cpp
----------
#include "idlist.h"

template <class T> typename IdSortedList<T>::iterator
IdSortedList<T>::insert(const T & item)
{
return data.end(); // dummy stupid code
}

template <class T> bool IdSortedList<T>::erase(double)
{
return false; // dummy stupid code
}


template03.cpp
---------------
#include <iosfwd>
#include "idlist.h"

class IntList : public IdSortedList<int> {
};


int main()
{
IntList l;
}

10 réponses

Avatar
Fabien LE LEZ
On Tue, 02 Nov 2004 23:00:33 +0100, Alain Cabiran :

j'ai un gros pb avec les liaisons


Non, tu as juste oublié de lire les nombreux messages, documents,
livres, etc., à ce propos.
En gros, tu as le choix entre utiliser un compilateur qui implémente
"export", ou mettre tous les "template <...> ..." dans le .h.


--
;-)

Avatar
Anthony Fleury
Alain Cabiran wrote:

Bonjour,

j'ai un gros pb avec les liaisons, j'ai testé avec g++ 2.95 g++ 3.0
g++ 3.3 et c++ builder :


Trois compilateurs qui ne supportent pas « export ».

si je groupe tout le code dans le même fichier, pas de problème
si je sépare en 2 cpp et un h, j'ai une référence indéfinie à la liaison
vers insert et erase quand je compile le tout.,
quelqu'un y comprend qqch ?


Oui !

idlist.h
[...]


template <class T> class IdSortedList {
[...]


idlist.cpp
template <class T> typename IdSortedList<T>::iterator
IdSortedList<T>::insert(const T & item)
{
return data.end(); // dummy stupid code
}

template <class T> bool IdSortedList<T>::erase(double)
{
return false; // dummy stupid code
}


Sans export, les définitions de fonctions template doivent être présentes
dans toutes les unités de traduction (donc en gros avec la définition de la
classe, comme les fonctions inline)
Plusieurs choix de conception après :

- mettre le tout dans un fichier dont on choisit l'extension (.tpp ou autre
à définir lors du projet), et c'est ce fichier qui sera inclu à la place
du .h.
- Tout mettre dans le .h (revient au même que le cas précédent)
- inclure le .cpp à la fin du .h et laisser les définitions des fonctions
template dans le .cpp (faut aimer)

Anthony
--
Alan Turing thought about criteria to settle the question of whether
machines can think, a question of which we now know that it is about as
relevant as the question of whether submarines can swim.
-- Dijkstra

Avatar
Aurelien REGAT-BARREL
Bonjour,

template <class T> class IdSortedList {


Question stupide : s'il s'agit d'une liste triée, quelle différence avec
std::set ou std::multiset ?

--
Aurélien REGAT-BARREL

Avatar
Fabien LE LEZ
On Wed, 3 Nov 2004 01:50:14 +0100, "Aurelien REGAT-BARREL"
:

Question stupide : s'il s'agit d'une liste triée, quelle différence avec
std::set ou std::multiset ?


J'imagine qu'il s'agit là d'une classe faite pour s'entraîner, pas de
code de production.


--
;-)

Avatar
Jean-Marc Bourguet
Alain Cabiran writes:

Bonjour,

j'ai un gros pb avec les liaisons, j'ai testé avec g++ 2.95 g++ 3.0
g++ 3.3 et c++ builder :

si je groupe tout le code dans le même fichier, pas de problème

si je sépare en 2 cpp et un h, j'ai une référence indéfinie à la
liaison vers insert et erase quand je compile le tout.,

quelqu'un y comprend qqch ?


Oui. C'est une FAQ (ou plutot ce devrait en etre une, c'est
certainement la question la plus posee sur ce groupe concernant les
templates). Il y a deux modele pour donner la definition de template:
- le modele d'inclusion ou la definition est donnee dans chaque
unite ou se trouve des instances -- c'est le seul modele
largement supporte par les compilateurs
- le modele separe ou la definition est exportee d'une unite de
compilation -- a ma connaissance 2 compilateurs le propose, Comeau
et Intel.

Pour une version plus longue, plus axee sur export (et sans exemple de
code, je me rend compte maintenant que j'aurais du en mettre)
http://www.bourguet.org/cpp/export.pdf

Toujours sur export, la doc de Comeau sur le sujet
http://www.comeaucomputing.com/4.0/docs/userman/export.html

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
Alain Cabiran
Bonjour,


template <class T> class IdSortedList {



Question stupide : s'il s'agit d'une liste triée, quelle différence avec
std::set ou std::multiset ?



le code que j'ai envoyé est un extrait de ce que je suis en train de
fabriquer. La vraie classe est prévue pour être utilisée (si si).

la question me surprend tellement c'est évident :

std::list<T>::iterator
std::set<T>::iterator

la différence, d'après ce que j'ai compris (et pris en pleine tête par
les compilateurs :-)) c'est que les éléments d'un set sont constants.

donc pas question, sans const_cast de faire joujou avec les membres.
Exemple :

std::list<Budget>::iterator it find(data.begin(), data.end(), FindId(myId));

if (it != data.end())
std::cout << it->nom();

de la même façon, je veux pouvoir effectuer :

std::list<Transaction>::iterator it find(data.begin(), data.end(), FindId(myId));

if (it != data.end())
it->setSomme(-400);

mais pas it->setDate(Date::today());

si je remplace list par set, ça explose ce qui est normal mais n'est
pas ce que je veux pouvoir faire. donc list triée et pas set.

de la même façon, la liste est triée par id (un timeval sous forme de
classe) donc en partant d'un std::list<IdObject> ç'aurait pu marcher
si ce *%@$ de polymorphisme fonctionnait sans pointeur.

or j'ai testé std:list<mere> et std::list<mere *> en push_backant
des filles et :

sans pointeur, pas de polymorphisme,
avec pointeur, pas de désallocation des ressources
(vu dans le bouquin de bs et constaté avec g++)

je me contente donc d'une

template <class T> IdSortedList

que je dérive et y insère des descendants (Budget, Modele,
Transaction, Repartition) d'un IdObject qui sait gérer uniquement
un timeval et chaque descendant étend (extends :-)) avec ses propres
spécificités.

je sais pas si c'est clair, je cogite sur ce truc depuis trèèèèèèèès
longtemps et j'ai le framework en tête (en plus du papier :-))

En tout cas merci à tout pour les réponses, j'ai compris, modifié le
code et ça marche, je peux continuer mon biniou.

Par contre, je ne sais pas où on peut mettre ça dans la faq. Sans
l'indice "export", je n'aurais jamais tilté la dessus. D'autant plus
que j'ai déjà lu le passage du bouquin de bs sur la clause export
mais je n'aurais jamais pensé à ça.

et pour cause, je pensais bêtement sans doute, que les template étaient
implémentés sous forme de macro en interne et que les compilos créaient
des classes différentes pour chaque spécialisation rencontrée. Ce n'est
pas le cas, tant pis. En plus ça explique la taille et le contenu des
entête stl :-)

merci à tous,

best regards comme on dit

Alain Cabiran

ps: je ne connais de java que "extends", "private à répétitions"
et "je reste c++, na." donc pas besoin de troller, j'en ai assez d'un
au boulot :-)


Avatar
Fabien LE LEZ
On Wed, 03 Nov 2004 22:32:11 +0100, Alain Cabiran :

avec pointeur, pas de désallocation des ressources


Avec un pointeur nu, effectivement.
Par contre, avec un pointeur intelligent, la situation est différente.


--
;-)

Avatar
Fabien LE LEZ
On Wed, 03 Nov 2004 22:32:11 +0100, Alain Cabiran :

que les template étaient
implémentés sous forme de macro en interne et que les compilos créaient
des classes différentes pour chaque spécialisation rencontrée.


Cette vision n'est pas très éloignée de la réalité. Et si tu imagines
que les templates sont des macros (définies avec #define), tu
comprendras pourquoi il faut tout mettre dans le .h.


--
;-)

Avatar
Mathieu Peyréga
- le modele separe ou la definition est exportee d'une unite de
compilation -- a ma connaissance 2 compilateurs le propose, Comeau
et Intel.


Il fait ça le compilo Intel ? c'est dans sa toute dernière version alors
parce que j'ai eu l'occasion d'essayer une version 7.x et elle ne le
faisait pas... (ou alors j'ai raté un épisode)

Mathieu
--
http://matioupi.free.fr/

Avatar
Jean-Marc Bourguet
Mathieu Peyréga writes:

- le modele separe ou la definition est exportee d'une unite de
compilation -- a ma connaissance 2 compilateurs le propose, Comeau
et Intel.


Il fait ça le compilo Intel ? c'est dans sa toute dernière
version alors parce que j'ai eu l'occasion d'essayer une
version 7.x et elle ne le faisait pas... (ou alors j'ai
raté un épisode)


La dernière version, d'après David VDV dans un message ici
même il n'y a pas très longtemps.

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