IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Valeur renvoyée par un opérateur


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut Valeur renvoyée par un opérateur
    Bonjour,

    J'ai encore une question à propos de mes opérateurs surchargés :

    Si je cherche à surcharger + dans une de mes classes, après avoir correctement surchargé +=, j'ai fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template <typename Elem>
    PolyD<Elem>& PolyD<Elem>:: operator + (PolyD V)
    { 
    V += (*this); 
    return V;
    }
    Ce qui fonctionne mais réflexion faite ça devrait planter royalement, vu que je renvois par référence un objet de portée locale, non ?
    Je vais devenir fou avec ces opérateurs partout ...

    merci

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Effectivement, tu renvoie une référence vers quelque chose qui sera détruit au moment de quitter la fonction...

    Ceci dit, assez bizarement, (en fait non: de manière très logique, si on suit la norme), si tu récupère la valeur de retour sous la forme d'une référence constante, cela fonctionnera sans problème, car une référence constante permet la construction d'un objet (qui deviendra temporaire pour la fonction dans laquelle tu récupère cette valeur)

    A ce sujet, je te proposerais bien la lecture (en anglais) de cet article

    Ceci dit, l'opérateur += peut renvoyer une référence parce qu'il renvoie... l'objet modifié, alors que l'opérateur + seul renvoie normalement... un nouvel objet, qui n'est donc ni l'opérande de gauche (l'objet en "cours") ni celui de droite (qui est donné en paramètre), il ne devrait donc pas renvoyer une référence

    Ce qu'il faudrait normalement faire, c'est:
    1. créer une variable du type ad-hoc qui soit la copie de l'objet en cours (*this)
    2. utiliser (éventuellement) l'opérateur += sur cette variable en donnant comme opérande de droite l'objet passé en argument
    3. renvoyer cette variable

    Sur une classe MaClasse, l'opérateur se présenterait donc sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    MaClasse MaClasse::operator+(const MaClasse& op) const
    {
        MaClasse temp= *this;
        temp+=op;
        return temp;
    }
    Nota: il n'est pas impossible que l'idiome copy and swap te vienne en aide pour une partie du travail
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Ceci dit, assez bizarement, (en fait non: de manière très logique, si on suit la norme), si tu récupère la valeur de retour sous la forme d'une référence constante, cela fonctionnera sans problème, car une référence constante permet la construction d'un objet (qui deviendra temporaire pour la fonction dans laquelle tu récupère cette valeur)
    On a eu cette discussion récemment avec un ami, et j'avoue que je veux bien une clarification là-dessus. Le code suivant est valide de manière incontestable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    A f() 
    { 
      A a; 
      return a; 
    }
     
    int main()
    {
      const A& localA = f();
      ...
    }
    Par contre, le code suivant fait planter gcc à l'utilisation de localA
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    const A& f() 
    { 
      A a; 
      return a; 
    }
     
    int main()
    {
      const A& localA = f();
      ...
    }
    En fait, le problème qu'on voit, c'est que autant, dans le cas de la valeur de retour, le compilateur sait statiquement où elle est allouée, et peut donc sans problème augmenter sa durée de vie, autant, dans le cas d'un renvoi de référence d'un objet alloué sur la pile en train d'être détruite, ce ne peut être fait que dynamiquement. Mais pourtant, ne pas le faire rompt le fait que la durée de vie d'un objet est étendu à celle de la référence constante...

    Donc, bug de gcc ou incompréhension de la norme de ma part ?

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le coup de la référence constante sur la valeur de retour, c'est un "truc" du langage.
    Mais il n'y a pas de "truc" pour les fonctions qui retournent directement une référence.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    Diable, comment ais-je fait mon compte pour ne pas me rendre compte que le code adapté était simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MaClasse MaClasse::operator+(const MaClasse& op) const
    {
        MaClasse temp= *this;
        temp+=op;
        return temp;
    }
    Je m'obstinais à vouloir renvoyer une référence

    Cela m'étonne toujours que mon code fonctionnait cependant, je vais essayer de lire ton article koala01

    Merci infiniment à tous (plus particulièrement à koala01 qui me tire d'embarras depuis quelques jours déja )

  6. #6
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Opérateur Voir le message
    Diable, comment ai-je fait mon compte pour ne pas me rendre compte que le code adapté était simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    MaClasse MaClasse::operator+(const MaClasse& op) const
    {
        MaClasse temp= *this;
        temp+=op;
        return temp;
    }
    Ou plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    const MaClasse MaClasse::operator+(const MaClasse& op) const
    {
        MaClasse temp(*this);
        temp+=op;
        return temp;
    }
    Il faut toujours utiliser le constructeur de copie, plutôt que la combinaison constructeur par défaut + affectation. Et il est préférable de (c'est à dire, il faut, sauf bonne raison de ne pas le faire (il y en a)) renvoyer un objet constant puisque c'est un temporaire.

    Le coup de la référence constante sur la valeur de retour, c'est un "truc" du langage.
    Mais il n'y a pas de "truc" pour les fonctions qui retournent directement une référence.
    En fait, la norme étant un peu chère pour quelqu'un qui n'en a pas besoin, je ne sais pas ce qu'elle dit exactement à ce propos. De ce que j'en comprenais, le "truc" était plus une conséquence heureuse d'un bout de la norme, pas que c'était un choix délibéré de départ. Est-ce bien un choix délibéré, qui concerne uniquement les références constantes sur les valeurs de retour d'une fonction, dans le corps de l'appelant ?

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    En fait, la norme étant un peu chère pour quelqu'un qui n'en a pas besoin, je ne sais pas ce qu'elle dit exactement à ce propos. De ce que j'en comprenais, le "truc" était plus une conséquence heureuse d'un bout de la norme, pas que c'était un choix délibéré de départ. Est-ce bien un choix délibéré, qui concerne uniquement les références constantes sur les valeurs de retour d'une fonction, dans le corps de l'appelant ?
    Si j'en croit l'article proposé par Koala, c'est dans la norme :
    Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself, and thus avoids what would otherwise be a common dangling-reference error. In the example above, the temporary returned by f() lives until the closing curly brace. (Note this only applies to stack-based references. It doesn't work for references that are members of objects.)

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Si j'en croit l'article proposé par Koala, c'est dans la norme :
    ...
    C'est justement le coeur du problème, est-ce vraiment ce que dit la norme ?

    Parce que sinon, le code suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const A& f() 
    { 
      A a; 
      return a; 
    }
     
    int main()
    {
      const A& localA = f();
      ...
    }
    devrait être valide... En effet, on renvoie un temporaire, dont on étend la durée de vie au moyen de l'affectation à une référence constante (le retour de la fonction), qui fait qu'il est encore valide dans l'expression const A& localA = f(), et on étend encore sa durée de vie dans main.

    Pourtant, ça plante dans gcc (je n'ai rien d'autre sous la main pour tester). Quelle subtilité j'ai raté ?

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    a n'est pas un "temporaire", c'est une variable. Sa durée de vie est fixée.
    Il n'y a pas de temporaire si c'est une référence qu'on retourne.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    a n'est pas un "temporaire", c'est une variable. Sa durée de vie est fixée.
    Il n'y a pas de temporaire si c'est une référence qu'on retourne.
    Même dans le cas suivant ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const A& f() 
    { 
      return A(); 
    }
    Il y a bien un temporaire.

    Cela dit, je viens de faire deux trois tests, et je pense avoir trouvé l'élément qui me manquait.

    Ce qui marche, c'est ça :
    ce qui ne marche pas, c'est ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const A& var = static_cast<const A&>(f());
    Lorsqu'on renvoie une référence vers A(), ce n'est pas une affectation, mais un cast. Donc, ça ne fonctionne pas, et c'est cohérent.

  11. #11
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    Il faut toujours utiliser le constructeur de copie, plutôt que la combinaison constructeur par défaut + affectation.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MaClasse a;
    MaClasse b = a;
    est un appel au constructeur par copie, ce n'est pas un appel au constructeur par défaut suivi d'un appel à l'opérateur d'affectation. C'est strictement identique à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MaClasse a;
    MaClasse b(a);

    Sinon, une différence que je vois entre et c'est qu'avec la première, on est certain que l'objet que l'on obtient est une copie anonyme, temporaire et inutilisée autre-part de la valeur de retour de la fonction, a priori la référence peut la récupérer sans risque en étendant sa durée de vie. Alors qu'avec la seconde, il est impossible de savoir d'où vient réellement la valeur de retour, à laquelle il peut arriver toutes sortes de choses. Typiquement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #include <iostream>
     
    class A {
    public:
    int x;
    A():x(0) {}
    };
     
    const A& ref(const A& a){
    return a;
    }
     
    int main(){
     
    A* pa = new A;
    const A &a = ref(*pa);
    delete pa;
    std::cout << a.x << std::endl;
    return 0;
    }
    Ceci-dit, ce code compile (et s'exécute ??!!) sous visual...

  12. #12
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    J'ai une dernière question si vous permettez.

    Dans une de mes classes polyS (qui hérite d'une classe vecteur) je redéfinis l'opérateur unaire - ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PolyS& operator - ();
    et de même dans ma classe vecteur j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual Vecteur& operator - ();
    Cependant réflexion faite je ne voyais pas l'interêt d'aller renvoyer une référence.
    J'ai donc plutôt changé cela en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PolyS operator - ();
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual Vecteur operator - ();
    Et ça ne passe pas à la compilation, il me dit qu'il y a une incompatibilité de types covariants ou je ne sais quoi.
    D'où cela peut-il bien provenir ?

    merci :-)

  13. #13
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 898
    Points : 1 915
    Points
    1 915
    Par défaut
    Un retour covariant c'est lorsque une méthode d'une classe fille redéfinit une méthode de la classe mère mais en ne respectant pas totalement le protoype de la méthode redéfinie et en ayant une valeur de retour d'un type dérivé du type originel. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Clonable{
    public:
    virtual Clonable& clone() const = 0;
    };
     
    class Impl : public Clonable{
    public:
    virtual Impl& clone() const; //retour covariant
    };
    C'est expliqué plus en détail dans la faq.

    Je suppose que dans le cas d'un pointeur ou d'une référence le compilateur tolère les retour covariant, mais pas dans le cas des valeurs. Par curiosité, quel compilateur utilises-tu ?


    Sinon, pourquoi penses-tu que ton opérateur devrait renvoyer une valeur ? Est-il illogique que l'on puisse appliquer une autre fonction ou un autre opérateur ? Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int i = 0;
    ++(++i);
    Ceci incrémente 2 fois la variable i, et c'est ce qui en est attendu. Cela pose-t-il problème dans ton cas ?

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Effectivement, le retour co-variant doit s'appliquer sur une référence ou sur un pointeur

    Il est à noter que l'on ne parle de retour co-variant que sur des méthodes virtuelles, mais qu'une situation proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class A
    {
        /*...*/
    };
    class B: public A
    {
        /*...*/
    };
    class Base
    {
        public:
            virtual A& foo();
    }
    class Derivee : public Base
    {
        public:
            virtual B& foo();
    }
    entraine également le retour co-variant (il n'y a aucun lien requis entre la classe qui contient la méthode et le type qui est renvoyé, mais les types renvoyés doivent faire partie d'une même "arborescence")

    Il faut aussi savoir que, si tu déclares une méthode virtuelle dans la classe de base, la méthode reste virtuelle dans la classe dérivée, même si tu ne le précise pas explicitement.

    Le résultat est que le compilateur considère que cette méthode surchargée met en oeuvre un retour co-variant, si la valeur de retour n'est pas la même dans la classe de base que dans la classe dérivée.

    Dans ton cas, il ne s'agit donc pas de trouver le moyen de faire effectuer un retour co-variant de manière correcte (en renvoyant, par exemple une référence) mais bien de rendre la méthode non virutelle (en supprimant le mot clé virtual de la déclaration dans la méthode de la classe de base) car, si tu travailles avec une instance de classe vecteur, le retour de méthode doit bel et bien être... une nouvelle instance de vecteur et non une nouvelle instance de PolyS
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Note: C'est peut-être un peu hors-sujet, mais je vois mal une méthode Clone() retourner une référence plutôt qu'un pointeur...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    Me revoilà, désolé pour le retard de ma réponse j'avais un peu perdu le topic de vue

    Ok je pense que je comprend mieux. Je n'ai de toute façon pas besoin de déclarer les opérateurs virtuels dans la classe de base, effectivement, je suis idiot

    Ca règle donc le problème.
    J'utilise DevC++, donc le compilateur c'est gcc si je me souviens bien.

    merci beaucoup à tous !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/09/2007, 15h59
  2. [Windev 9] Valeur renvoyée par une fenêtre
    Par Romanops dans le forum WinDev
    Réponses: 10
    Dernier message: 04/01/2007, 17h54
  3. Valeur renvoyée par interrupteur (check box)
    Par nath-0-0 dans le forum WinDev
    Réponses: 8
    Dernier message: 29/11/2006, 16h33
  4. Réponses: 1
    Dernier message: 31/07/2006, 13h54
  5. [SQL] php et recuperation d'une valeur renvoyée par une fonction sql
    Par highman dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 21/06/2006, 15h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo