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

Langage C++ Discussion :

observer_ptr et autres considérations


Sujet :

Langage C++

  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 294
    Billets dans le blog
    2
    Par défaut observer_ptr et autres considérations
    Bonjour,

    je suis tombé par pseudo-hasard sur cette page:
    http://en.cppreference.com/w/cpp/exp...l/observer_ptr

    Il s'agit d'un pointeur intelligent qui ne possède pas l'objet pointé.
    Autrement dit, c'est un pointeur intelligent qui ne fait rien, ni lors de l'assignation (pas de compteur), ni en fin de vie (il ne touche pas à l'objet pointé).
    Autrement dit, ce n'est finalement rien d'autre qu'un pointeur nu renommé.
    Autrement dit, on pourrait proposer une implémentation de observer_ptr comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename T>
    using observer_ptr = T*;
    Du coup, ça me ramène à une de mes vieilles interrogations: l'utilisation de pointeurs nus est-elle si diabolique qu'on le dit?
    Moi personnellement, j'utilise des pointeurs nus dans mes programmes, mais en respectant la règle d'or suivante: jamais, Ô grand jamais, de delete (donc pas de "new nu", j'y reviendrai). Autrement dit, je m'octroie le droit d'utiliser des pointeurs nus, à condition que ceux-ci ne soient jamais propriétaires des objets pointés. Avec pour conséquence assumée (et parfois souhaitée) que ce pointeur puisse être null. Et jusqu'ici, sauf dans d'improbables cas de terrorisme orienté objet (par exemple utiliser un pointeur déclaré statique et initialisé sur une référence), mes programmes sont très stables.

    Au final, je me demande donc si la polémique du pointeur nu ne serait pas un faux problème. A l'instar du RAII qui est mal nommé, le problème du pointeur n'est pas sa création, mais sa destruction. Mais sa création (construction) détermine sa destruction. Si on créée un pointeur avec un "new nu", c'est à dire un new en dehors de toute forme d'encapsulation (notamment dans un smart pointer), alors il faudra faire un delete. Si en revanche on utilise un new encapsulé dans une structure raii-esque (de type smart pointer notamment), alors on a pas besoin de delete et alors tout va bien, puisque le cycle de vie sera géré de façon simple et intelligente par la structure en question.

    Et donc, et pour finir, j'en arrive à me demander quelle peut bien être l'utilité de cet étrange animal, l'observer_ptr.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    307
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 307
    Par défaut
    Il m'arrive aussi d'utiliser parfois des pointeurs nus non responsable de la vie d'un objet : la limite principale c'est que si l'objet est détruit alors on risque d'obtenir un comportement indéfini et ça c'est mal car ça peut faire n'importe quoi et cela peut etre difficile à trouver et corriger.

  3. #3
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    À mon sens, le problème n'est pas le pointeur, mais l'intention que véhicule le pointeur: plein de questions sans réponses.
    - Ressource managée ? Qui est propriétaire ? Comment libérer ?
    - Pointeur pouvant être nul ?
    - Tableau ou simple valeur ? Bon ok, on donne une taille si c'est un tableau.

    En mettant observer_ptr, on répond au moins aux 2 premières questions.
    Par contre, je crois que delete observer_ptr; compile quand même. Dommage, l'opérateur aurait pu être supprimé,

  4. #4
    Invité
    Invité(e)
    Par défaut
    @r0d : j'utilise parfois des pointeurs nus de la même façon que toi. Du coup, l'apparition de ce observer_ptr est plutôt une bonne nouvelle : d'une part çà met un nom sur cet usage des pointeurs (+ les vérifications qui vont bien) et d'autre part çà semble indiquer que cet usage n'est pas complètement idiot.

    @jo_link_noir :
    - avec les array et vector, je ne vois plus vraiment de raison d'utiliser des pointeurs pour les tableaux, même si c'est effectivement encore autorisé
    - pour le delete, je ne suis pas sûr de te comprendre; le code delete observer; signifie que tu as créé un observer_ptr dynamiquement (avec un new), ce qui est un peu tordu. Ne voudrais tu pas dire plutôt delete observer.get(); ? Et dans ce cas c'est effectivement dommage si çà compile.

  5. #5
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Tu as la réponse à ces questions dans les C++ core guidelines:
    https://github.com/isocpp/CppCoreGui....md#S-resource

    c'est bien une question de gestion de propriété des ressources. Mais observer_ptr est à priori une mauvaise idée, car il n'apporte rien par rapport à un pointeur brut. Ou dit autrement : l'usage recommandé du pointeur brut est en tant que observer_ptr. Et donc, devoir spécifier à chaque fois le terme "observer_ptr" pour un comportement par défaut est un mauvais design.

    En revanche, ses petits copains du même type : owner<T*>, not_null<T*> apportent une réelle plus-value. L'intérêt de les déclarer sous forme de simple alias (avec using) au lieu d'être des wrappers fait qu'ils n'ont aucun impact à l'édition des liens (pas de modification du name mangling et donc de l'ABI).

    Alors oui le compilo ne peut pas vérifier le respect de la convention d'usage, mais un outil d'analyse statique de code oui. Et d'ailleurs, il y en a un qui est censé arriver bientôt, en open source. Tout est expliqué ici :

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 760
    Par défaut
    @nokomprendo: Plutôt dans la situation où on "oublie" que ptr n'est qu'un observable. Vu qu'observer_ptr possède un cast vers T*, delete pourrait fonctionner. Sauf qu'hier, je n'avais pas vu que le cast était explicite .

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel Voir le message
    c'est bien une question de gestion de propriété des ressources. Mais observer_ptr est à priori une mauvaise idée, car il n'apporte rien par rapport à un pointeur brut. Ou dit autrement : l'usage recommandé du pointeur brut est en tant que observer_ptr. Et donc, devoir spécifier à chaque fois le terme "observer_ptr" pour un comportement par défaut est un mauvais design.

    Pas forcément. Le pointeur brut correspond à la fonctionnalité bas-niveau. La guideline R.3 suggère effectivement de l'utiliser comme observer parce que c'est le comportement par défaut mais rien n'oblige à l'utiliser ainsi. Du coup, cet observer_ptr permet de clarifier les choses et rend cette guideline inutile.

    @jo_link_noir : exact, je n'avais pas vu le cast. Et effectivement avec le "explicit", il faut quand même sacrément en vouloir pour faire le vilain delete.

  8. #8
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Personnellement je pense qu'observer_ptr a de fortes chances de disparaître dans le futur et donc je ne recommanderais pas son usage.

    Dans la vidéo à 1:32:30, Stroustrup explique pourquoi il ont privilégié owner<t> plutôt que non_owner<T> (= observer).

    https://youtu.be/1OEu9C51K2A?t=1h32m30s

    De manière générale, la redondance de syntaxe est quelque chose qui vieillit mal.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Justement, ce n'est pas que de la syntaxe, il y a un peu de sémantique également.
    Je pense qu'on peut comparer çà à la valeur nullptr et au type bool : on peut facilement s'en passer mais c'est quand même sympa de les avoir.
    Mais je suis d'accord que çà ne va sûrement pas révolutionner le langage.

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    En ce qui concerne ta question (les pointeurs nus sont-ils vraiment si diaboliques ), je donnerais volontiers une réponse de normande variant entre "non, sauf si " et "oui, à moins que"... Je m'explique :

    Ils sont diaboliques lorsqu'il n'y a aucune convention indiquant explicitement qu'ils ne peuvent pas être responsable de la durée de vie de l'objet pointé, mais ils ne posent aucun problème s'ils ne sont utilisés que pour représenter une ressource qui peut ne pas exster (et que l'on évite donc toute gestion à coup de new et de delete dessus).

    Si, pour une raison ou une autre, on commence à envisager d'invoquer new ou delete sur un pointeur nu, cela va mal se terminer dans une très grosse majorité des cas, et ce n'est que parce que cette possibilité est encore trop encrée dans les mentalités qu'ils sont encore diabolisés.

    Ceci dit, l'arrivée de std::optional risque de limiter encore un peu les cas dans lesquels il s'avérera effectivement intéressant de recourir à un pointeur nu (ne pouvant, quoi qu'il arrive, prendre aucune participation dans la propriété de l'objet pointé, nous sommes d'accord )

    Si bien que je suis un peu circonspect à l'idée d'utiliser std::observer_ptr... Car, l'un dans l'autre, je dois lui reconnaitre deux avantages :
    1. Cette classe explicite très clairement le fait qu'il n'y a aucune notion de responsabilité vis à vis de la ressource pointée. Sémantiquement parlant, cela peut s'avérer être une bonne chose
    2. Cette classe expose une interface commune au std::unique_ptr avec ses fonctions reset, release, swap et get. Associée à la sémantique de "non propriété", cette interface pourrait faciliter les choses lorsqu'il s'agira de "traquer" les éventuels changements de valeurs "inadéquats".

    Par contre, je ne suis pas forcément sur de l'intérêt des opérateur de déréférencement ou de conversion (autre qu'en booléen), et je dois reconnaitre être de l'avis d'Aurélien quand il dit que le fait de devoir spécifier systématiquement qu'il s'agit d'un observer, alors que nous aurions pu simplement décider une bonne fois pour toute que c'était la sémantique associée aux pointeurs nus et assez illogique en soi.
    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

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/04/2011, 14h00
  2. [langage] Comparer Perl avec d'autres langages comme C ?
    Par Anonymous dans le forum Langage
    Réponses: 3
    Dernier message: 10/08/2002, 23h52
  3. Réponses: 2
    Dernier message: 10/07/2002, 11h51
  4. Réponses: 2
    Dernier message: 21/05/2002, 10h25
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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