Partage
  • Partager sur Facebook
  • Partager sur Twitter

NUL terminated strings en C

Hasard ou nécessité ?

    7 avril 2021 à 19:00:57

    Bonjour,

    histoire de ne pas pourrir un autre sujet (Vector en C) par une collection de posts HS, dont je me sens bien malgré moi à l'origine par une boutade qui n'aurait jamais due provoquer tant de réactions, je vous propose de venir continuer le débat ici même, MichelBillaud et PierrotLeFou :)

    Pour rappel :

    michelbillaud a écrit:

    White Crow a écrit:

    EjeXjdk a écrit:

    Pourquoi le choix de mettre une valeur sentinelle en fin de chaîne de char est contestable ?

    C'est plus une question de religion au final …

    N'avoir qu'une sentinelle de fin t'oblige à parcourir tout le contenu pour en connaître la taille … ce qui n'est a priori pas très efficace. Du moins beaucoup moins que de conserver la taille dans un champ. En revanche si tu conserves la taille alors il te faudra la mettre à jour à chaque modification l'impactant.

    Edité par White Crow il y a environ 3 heures


    C'est pas une question de religion. Il y a des critères rationnels.

    • si on n'a pas besoin de la taille : on s'en fout
    • si on en a besoin :
    1. avec la sentinelle : chaque fois qu'on en a besoin, il faut la recalculer, ce qui prend un temps proportionnel à la longueur de la chaine
    2. avec un compteur : quand on en a besoin on y a accès directement. Et quand on modifie la chaine, la modification de la taille se fait aussi directement. Et si l'accès aux chaînes est "encapsulé" correctement dans des fonctions (le minimum qu'on peut attendre de la bibliothèque d'un langage qui manipule des chaines...) il n'y a pas à y penser ou à risquer d'oublier.
    Donc y a pas photo.
    Le problème, c'est que C est un langage qui, au départ, était officiellement un langage sans chaînes de caractères (intégrées au langage), comme en témoigne l'introduction du K & R :

    Il se trouve que les programmeurs se sont débrouillés avec l'ersatz qui constitue le pointeur sur le premier caractère + valeur sentinelle, sans indication de la taille ni de la capacité maximale. Et que les fonctions qui jouaient avec se sont retrouvées dans la norme, donc consacrées comme "la" façon de faire en C. Un petit souci de conception, qui, finalement, aura causé des milliards de dollars de dégâts en termes de plantages et piratages par buffer overflow.
    Bref, l'aspect religieux là dedans, c'est peut être le refus de rentrer dans des choix rationnels.


    PS : à la même époque, en Pascal, il n'y avait pas non de chaines de caractères dans le standard. Juste des tableaux de caractères de taille fixe, complétés par des espaces à droite au besoin.  Alors que Basic, si.

    -
    Edité par michelbillaud il y a environ 7 heures

    PierrotLeFou a écrit:

    Dans la plupart des cas, Basic était un langage interprété, mais j'ai connu un cas où il était compilé.
    Je ne me rappelle pas ce qu'on faisait pour allonger une chaîne.

    michelbillaud a écrit:

    Avec +. Le guide GW BAsic, chapitre 6

    http://www.antonis.de/qbebooks/gwbasman/chapter%206.html

    Strings can be concatenated by using the plus (+) sign. For example:

    10 A$="FILE":B$="NAME"
    20 PRINT A$+B$
    30 PRINT "NEW " + A$+B$
    RUN
     FILENAME
     NEW FILENAME

     donc pour ajouter quelque chose au bout : concaténer et réaffecter

    A$ = A$ + "*"



    -
    Edité par michelbillaud il y a moins de 30s

    Juste pour info, les nul terminated string (ou AsciiZ) viennent probablement de l'architecture des PDP 7/10/11 qui possédaient très peu de mémoire, et une instruction ASCIZ dans le macro assembleur qui gérait tout ça très bien. Les caractères ASCII codés sur 7 ou 6 bits étaient packés dans un double mot de 36 bits (6*6 ou 7*5). L'utilisation d'une taille valait alors 5 caractères ascii …

    Ensuite viennent les flame wars (le plus souvent C vs Pascal en effet) sur lesquelles je ne vais pas m'attarder.

    sources :

    → https://en.wikipedia.org/wiki/Null-terminated_string 

    → https://en.wikipedia.org/wiki/MACRO-10 

    → http://www.bitsavers.org/pdf/dec/pdp10/1970_PDP-10_Ref/1970PDP10Ref_Part2.pdf 

    → https://www.bell-labs.com/usr/dmr/www/chist.html 

    → la grande guerre  C~Pascal vue par K → https://www.lysator.liu.se/c/bwk-on-pascal.html 

    • Partager sur Facebook
    • Partager sur Twitter
      8 avril 2021 à 2:38:28

      Pour Basic, le fait de le revoir m'est revenu à la mémoire.
      J'ai travaillé en Pascal à l'âge des dinosaures avec des mots clés français: write -> ecrire, writeln -> ecrireln
      Il me semble qu'on écrivait un caractère à la fois et qu'on devait savoir la longueur des chaînes à l'avance.
      Je ne connaissais pas la fonction length() en Pascal.
      J'ai commencé avant le C89 et les chaînes étaient déjà terminées par un '\0'
      À l'époque, même les système Unix n'avaient pas beaucoup de mémoire.
      J'avais droit à 10Mb sur disque, alors ...
      Tout le monde disait à l'époque que C était de "l'assembleur de haut niveau".
      Pour avoir fait un peu de C++ et surtout du Python, je me rend compte de la limitation de cette contrainte.
      Par contre, l'espace occupé en mémoire est plus grand que les caractères eux-mêmes.
      On aura trois priorités:
      + la vitesse d'exécution (même si Python est interprété)
      + la mémoire occupée.
      + la simplicité du code
      Comme l'a suggéré White Crow, on peut faire des fonctions pour encapsuler le code et le simplifier un peu.
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        8 avril 2021 à 7:41:21

        Faudrait remonter dans les docs des systèmes d'exploitation  précédents et voir quels appels étaient fournis pour l'affichage de texte (go Multics!)

        -
        Edité par michelbillaud 8 avril 2021 à 11:18:42

        • Partager sur Facebook
        • Partager sur Twitter

        NUL terminated strings en C

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown