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 :

optimisation de ma fonction strlen


Sujet :

C

  1. #21
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    [Je me fais un peu l'avocat du diable, mais je reste sur ma position et ne suis pas d'accord avec toi]

    Citation Envoyé par Kirilenko Voir le message
    la fonction strlen de la bibliothèque standard de C est généralement optimisée à la main afin de passer correctement sur toutes les implémentations
    On peut discuter longuement de ce qu'on appelle "passer correctement"

    Citation Envoyé par Kirilenko Voir le message
    De plus, ce code n'obéit pas aux contraintes qui aboutissent à l'élaboration d'un seul point de sortie,
    Oui, enfin ca, suffit de lire le commentaire en dessous "ou equivalent" qui permet de penser que l'on peut aussi ecrire la chose suivante :

    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
    int my_strlen (chaine)
    {
      int return_value;
     
      if (chaine == NULL)
      {
        return_value = -1;
      }
      else
      {
        return_value = /* code qui calcule la longueur de la chaine */
      }
     
      return return_value;
    }
    Le fait de passer par une variable n'est pas obligatoire.

    Citation Envoyé par Kirilenko Voir le message
    il agrandit le domaine de définition de la fonction, ce qui peut se révéler problématique pour l'appelant (beaucoup de codes différents à traiter au cas par cas).
    Interessant. Tu es donc en train de dire qu'il vaut mieux obtenir un magnifique segfault au lieu d'agrandir le domaine de definition en pouvant retourner -1 ?
    C'est un point de vue tres interessant, mais je ne suis pas certain que le client qui achete ton code soit de cet avis...


    Citation Envoyé par Kirilenko Voir le message
    C'est un thème subjectif, mais je reste persuadé que, pour une fonction de la bibliothèque standard de C (qui se doit d'être une bibliothèque « générique »), il serait préjudiciable de privilégier la sécurité aux dépens des performances, alors que l'appelant peut très bien faire la vérification à sa place (et d'ailleurs, peut-être l'a-t-il déjà fait, ce qui, dans ce cas, ferait une vérification redondante).

    [...]norme C11
    Tu fais bien de parler de norme.
    C99 introduit (entre autre) snprintf, qui est exactement le contraire de ce que tu preconises.
    C11 introduit le Bound-checking, c'est a dire la verification qu'une variable est dans sa plage de donnee

    Il y a surement d'autres exemples du meme genre, mais je pense que tu vois ou je veux en venir : l'appelant peut tout a fait faire ces verifications a la place du compilateur, et pourtant l'evolution du langage tend vers ces doubles verifications.

    Citation Envoyé par Kirilenko Voir le message
    Enfin, pour être à cheval sur le vocabulaire : strlen calcule la longueur d'une chaîne, or, NULL n'est pas une chaîne.
    Pour etre encore plus precis, strlen calcule le nombre de caracteres different de '\0' de la suite de char dont le premier est indique par le pointeur sur char passe en parametre - pointeur qui peut etre NULL.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  2. #22
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Oui, enfin ca, suffit de lire le commentaire en dessous "ou equivalent" qui permet de penser que l'on peut aussi ecrire la chose suivante :

    [...]

    Le fait de passer par une variable n'est pas obligatoire.
    Je vois ; tu es donc un partisan des conditions imbriquées. C'est tout à ton honneur, mais je ne suis pas convaincu par la maintenabilité du code par la suite. Ne serait-ce que pour les niveaux de profondeurs qui seront ainsi créés. Après, je respecte ce choix, qui est certes sympathique sur des fonctions utilitaires, mais qui se complique dans le cas de points d'entrées.

    Interessant. Tu es donc en train de dire qu'il vaut mieux obtenir un magnifique segfault au lieu d'agrandir le domaine de definition en pouvant retourner -1 ?
    C'est un point de vue tres interessant, mais je ne suis pas certain que le client qui achete ton code soit de cet avis...
    Ça, c'est parce que strlen est une fonction relativement simple ; dans le cas où la fonction prend plusieurs arguments, cela crée d'autres vérifications. Dans ce cas-là, tu as deux possibilités : soit tu agrandis le domaine de définition (et comme la plupart de ces nouvelles valeurs sont issues de bogues de programmation, l'appelant ne saura généralement pas quoi en faire), soit tu réutilises ton ancienne valeur, auquel cas l'appelant ne pourra pas déterminer explicitement la cause de l'erreur... De toute manière, si tu en viens à passer un pointeur nul vers une telle fonction, il y a de fortes chances que la maison soit en feu...

    Tu fais bien de parler de norme.
    C99 introduit (entre autre) snprintf, qui est exactement le contraire de ce que tu preconises.
    Au contraire d'aberrations comme strncpy, je suis favorable à des fonctions comme snprintf dans le cas d'applications prônant la sécurité, mais ce n'est pas du tout le même public qui est visé. snprintf est une fonction lourde (de par sa caractéristique de fonction formatée), ça ne rentre pas dans l'optique d'une fonction utilisable dans des contraintes temps-réel par exemple. Or, strlen étant utilisée souvent, et par un public varié, on ne peut pas faire de telles suppositions.

    Et, encore une fois, la vérification de multitudes d'arguments ne me semble pas être viable sur certaines implémentations... Dans le cas de fonctions appelées en cascade, tu fais les vérifications à chaque fois ?

    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
    #include <stddef.h>
     
    void
    f(char *p)
    {
        if (p != NULL) /* ... */
    }
     
    void
    g(char *p)
    {
        if (p != NULL) f(p);
    }
     
    void
    h(char *p)
    {
        if (p != NULL) g(p);
    }
    Il y a surement d'autres exemples du meme genre, mais je pense que tu vois ou je veux en venir : l'appelant peut tout a fait faire ces verifications a la place du compilateur, et pourtant l'evolution du langage tend vers ces doubles verifications.
    Je dirais plutôt que l'évolution du langage préfère garder sa généricité. D'une part, comme tu l'indiques, en améliorant la sécurité (suppression de gets [C11], bounds checking [C11], snprintf [C99], etc.), mais sans pour autant négliger les applications nécessitant quelques performances (pointeurs restreints [C99], améliorations de la définition de strict aliasing [C99]). C'est une des seules normes de langage qui se prononce en faveur de l'optimisation, et je trouve que ça prouve bien la volonté de préserver la dualité du langage. Or, la vérification obsessionnelle des paramètres d'une fonction ne me semble entrer dans une telle optique.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  3. #23
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Je pense que nous utilisons tous deux le C dans des contextes differents, d'ou la difference de points de vue d'utilisation -- puisque nous sommes d'accord sur le fond.



    Citation Envoyé par Kirilenko Voir le message
    Dans le cas de fonctions appelées en cascade, tu fais les vérifications à chaque fois ?

    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
    #include <stddef.h>
     
    void
    f(char *p)
    {
        if (p != NULL) /* ... */
    }
     
    void
    g(char *p)
    {
        if (p != NULL) f(p);
    }
     
    void
    h(char *p)
    {
        if (p != NULL) g(p);
    }
    Oui, car dans mon domaine (demons qui tournent h24), l'application doit etre capable de resister a n'importe quel connerie que l'utilisateur pourrait faire. J'ai vu des utilisateurs supprimer une memoire partagee sur un programme de surveillance ; la version suivante etait donc resistante a ce genre de conneries (re-creation de la zone memoire en cas d'absence). C'est debile, mais c'est une contrainte qui m'est imposee.
    [Et je n'aurai presque pas ete surpris qu'un utilisateur bienveillant decide de changer la valeur d'un pointeur a NULL s'il avait pu le faire.]

    A contrario, dans les cas ou un test de plus ou de moins est important, effectivement, tester chaque pointeur a NULL est une perte de temps evidente -- et si ce cas (tres) improbable se produit, il est (presque) acceptable que l'application plante.

    Quant aux benefices eventuels de C11, c'est un autre debat
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #24
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Effectivement, la divergence de point de vue doit venir de là. Je code plus en embarqué, et j'ai rarement affaire à des utilisateurs aussi tordus ! Merci pour ce témoignage en tout cas, cela montre bien l'ambiguïté de l'utilisation du C et de ce sujet.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  5. #25
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Je pense que nous utilisons tous deux le C dans des contextes differents, d'ou la difference de points de vue d'utilisation -- puisque nous sommes d'accord sur le fond.
    Salut
    Personnellement je suis adepte de la philosophie originelle (peut-être est-elle encore d'actualité) qui est "les fonctions ne vérifient rien, c'est au programmeur de le faire". Ainsi le panel est le plus large possible. Ceux qui veulent du très rapide ont une fonction qui ne checke rien et qui est la plus rapide possible et celui qui veut tout contrôler peut lui-même développer ses propres contrôles en amont (mais effectivement il doit le faire)...

    Citation Envoyé par gangsoleil Voir le message
    J'ai vu des utilisateurs supprimer une memoire partagee sur un programme de surveillance ; la version suivante etait donc resistante a ce genre de conneries (re-creation de la zone memoire en cas d'absence). C'est debile, mais c'est une contrainte qui m'est imposee.
    Je compatis.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Optimisation d'une fonction
    Par BNS dans le forum C++
    Réponses: 7
    Dernier message: 15/12/2007, 22h25
  2. Réponses: 6
    Dernier message: 27/06/2007, 16h44
  3. Trou de mémoire : fonction strlen()
    Par bit_o dans le forum C
    Réponses: 3
    Dernier message: 30/04/2007, 23h20
  4. Comportement bizarre de la fonction strlen
    Par clampin dans le forum C
    Réponses: 4
    Dernier message: 30/12/2006, 14h00
  5. [PHP-JS] Fonction strlen en php
    Par viny dans le forum Langage
    Réponses: 20
    Dernier message: 04/10/2006, 14h09

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