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 :

pb type passage argument fonction pointeur


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 19
    Par défaut pb type passage argument fonction pointeur
    Bonjour,
    je me remets doucement au c (avec le compilateur SDCC) sur du vieux matériel (des années 80) et ça pique un peu... Bref, j'ai une fonction à laquelle je passe un tableau de int et que j'utilise dans la fonction pour écrire dedans. Aucun problème . En gros mon code :

    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
    void fonction1() 
    {
    	unsigned int x[200];
     
    fonction 2(x);
     
    ...
    }
     
    void fonction2(unsigned int px[])
    {
    ...
    unsigned char toto=0;
    ...
    px[y] = (unsigned char) toto;
    ...
    }
    Aucun problème. Sauf que mon tableau x contient des unsigned char, donc j'essaie de gagner de la place (car je bosse sur une machine très limitée).
    donc si je mets :

    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
    void fonction1() 
    {
    	unsigned char x[200];
     
    fonction 2(x);
     
    ...
    }
     
    void fonction2(unsigned char px[])
    {
    ...
    unsigned char toto=0;
    ...
    px[y] = (unsigned char) toto;
    ...
    }
    Là ça ne marche plus... pas d'erreur de compil, mais visiblement l'écriture dans le tableau perd les pédales et écrit n'importe où (au point de faire rebooter la machine).

    Bref je ne comprends pas où je me plante...

    ps : si je mets dans la declaration de f2 "unsigned char *px" à la place de "unsigned char px[]", c'est pareil...

    MERCI

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 487
    Par défaut
    Hello,

    Citation Envoyé par henri_b Voir le message
    je me remets doucement au c (avec le compilateur SDCC) sur du vieux matériel (des années 80) et ça pique un peu...
    Sympa, quel genre de machine ? :-)

    Là ça ne marche plus... pas d'erreur de compil, mais visiblement l'écriture dans le tableau perd les pédales et écrit n'importe où (au point de faire rebooter la machine).

    Bref je ne comprends pas où je me plante... ps : si je mets dans la declaration de f2 "unsigned char *px" à la place de "unsigned char px[]", c'est pareil... MERCI
    Ce n'est probablement pas dû au type de donnée utilisé mais à l'index y qui doit dépasser le tampon. Comme ton extrait ne nous dit rien de ce fameux y, on ne peut rien en déduire. Il nous faudrait un peu plus de code (voire le fichier entier si c'est possible).

    Bon courage.

  3. #3
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 315
    Billets dans le blog
    5
    Par défaut
    Bonjour.

    Il faut faire attention à une information que malheureusement nous avons tendance à ne pas prendre en compte. : la taille de la pile.

    Hormis la réponse d'Obsidian qui reste valable, peut-être que la taille de la pile est dépassée lorsque tu déclares un tableau de taille 200. Essaie avec une toute petite taille (10 par exemple) pour voir si le comportement erratique continue ou si tout rentre dans l'ordre.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par henri_b Voir le message
    pas d'erreur de compil
    En compilant avec les options les plus sévères (-Wall -Werror) ???

    Citation Envoyé par henri_b Voir le message
    Bref je ne comprends pas où je me plante...
    Oui enfin déjà le code que tu montres est assez désinvolte. Indentation anarchique, appel de "fonction 2" alors qu'elle se nomme "fonction2", cast au hasard (ben oui, toto est déjà unsigned char donc t'as pas à le caster !!!), variable "y" sortie de mon sproumpf... Si le reste est à l'identique les possibilités de plantage sont en proportion. Le C ne supporte pas l'"à peu près" et doit se prendre avec sérieux et rigueur, parce qu'il ne te fera aucun cadeau. Déjà sa philosophie c'est "le programmeur sait ce qu'il fait" et cela veut tout dire.

    Citation Envoyé par henri_b Voir le message
    En gros mon code...
    Non, en détail ton code exact et complet sinon on ne pourra rien faire. Sauf à produire nous-même un code d'exemple... éventuellement...

    Code c : 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
    22
    23
    24
    25
    26
    27
    #include <stdio.h>
     
    void fonction1();
    void fonction2(unsigned char[]);
    void affiche(unsigned char[]);
     
    void fonction1() {
    	unsigned char x[200];
     
    	fonction2(x);
    	affiche(x);
     
    }
     
    void fonction2(unsigned char px[]) {
    	for (size_t i=0; i < 200; i++)
    		px[i] = (unsigned char)i;
    }
     
    void affiche(unsigned char px[]) {
    	for (size_t i=0; i < 200; i++)
    		printf("px[%ld]=%d\n", i, px[i]);
    }
     
    int main() {
    	fonction1();
    }
    Compilé sur un Linux avec les flags les plus sévères, ce code produit exactement le résultat escompté.
    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]

  5. #5
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 551
    Par défaut
    Bonsoir,
    Code c : 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
    #include <stdio.h>
    
    void fonction1();
    void fonction2(unsigned char[]);
    void affiche(unsigned char[]);
    ......
    
    void fonction2(unsigned char px[]) {
        for (size_t i=0; i < 200; i++)
            px[i] = (unsigned char)i;
    }
    
    void affiche(unsigned char px[]) {
        for (size_t i=0; i < 200; i++)
            printf("px[%ld]=%d\n", i, px[i]);
    }
    
    int main() {
        fonction1();
    }

    Il est possible que cette idée fonctionne, mais le fait qu'il n'y ait pas de contrôle sur la taille du buffer entraîne un comportement indéterminé, comme Obsidian l'a souligné sur un possible écrasement. Dans la fonction2(unsigned char px[]), le code écrit systématiquement jusqu’à px[199] sans vérifier si le tableau fourni dispose réellement de cette taille. Si un tableau plus petit est utilisé comme argument, cela provoquera un débordement du buffer, ce qui conduira inévitablement le programme à un comportement indéfini. Et oui, le langage C ne garantit pas la sécurité des accès mémoire. C'est donc de la responsabilité du développeur de le faire. Néanmoins, sans plus de code exhaustif...

    Code C : 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
    22
    23
    24
     
    #define SIZE_BUFFER    200
     
    void fonction2(unsigned char px[], size_t taille) {
        if( px == NULL || taille == 0)
            return;  // paramètre incorrect
        for (size_t i = 0; i < taille; i++)
            px[i] = (unsigned char)i;
    }
     
     
    void affiche(unsigned char px[], size_t taille) {
        if( px == NULL || taille == 0)
            return; 
        for (size_t i = 0; i < taille; i++)
            printf("px[%zu] = %d\n", i, px[i]);
    }
     
     
    void fonction1() {
        unsigned char x[SIZE_BUFFER];
        fonction2(x, sizeof(x));   // passer la taille
        affiche(x, sizeof(x));
    }
    La philosophie du langage C veut que le programmeur soit responsable de la réalisation explicite de ces vérifications

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    mais le fait qu'il n'y ait pas de contrôle sur la taille du buffer entraîne un comportement indéterminé
    Absolument pas. Enfin en partant de l'hypothèse standard que le programmeur, censé savoir ce qu'il fait, appelle les fonctions avec un tableau cohérent avec ces dernières (et de toute façon s'il les appelle avec un tableau incohérent on ne peut pas le vérifier).

    Citation Envoyé par sambia39 Voir le message
    , ...le code écrit systématiquement jusqu’à px[199] sans vérifier si le tableau fourni dispose réellement de cette taille.
    Il est impossible, totalement impossible, en C, de vérifier qu'un tableau possède bien la taille qu'on lui prête. Et même ton code d'exemple ne garantit rien en ce sens (rien n'interdit d'appeler fonction2(tab, 5000) et là vas-y, explique-moi comment ça va se comporter ton prodige ???).
    Dans les deux cas c'est donc au programmeur d'appeler les fonctions avec les bons paramètres (un tableau de taille 200 dans mon cas, un tableau de taille 200 PLUS la valeur 200 dans le tien). Donc non seulement ton code n'offre aucune sécurité supplémentaire mais nécessite plus de paramètres donc plus de risques de se tromper. Surtout que le sizeof est un très mauvais conseil (un débutant qui voit ça s'imagine que c'est gagné puis un jour il reçoit un tableau en paramètre (un pointeur donc), veut voir sa taille, appelle sizeof() et se retrouve avec 4 )

    En fait ton code offre juste des fonctions plus génériques, qui ont l'avantage de pouvoir traiter des tableaux de tailles diverses(tableau de taille 500 + valeur 500, tableau de taille 1000 + valeur 1000) mais n'apporte rien au problème du PO qui était de pouvoir transmettre un tableau initial à différentes fonctions et surtout n'offre aucune garantie supplémentaire puisque le C ne sait pas, ne peut pas vérifier les tailles d'un tableau dont il n'a que le pointeur. Bref il sert à que dalle.

    Accessoirement c'est dommage de créer un #define (ça c'est super pour faciliter l'évolution) et de ne pas savoir l'utiliser plus intelligemment que ça...

    Code c : 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
    22
    #define SIZE_BUFFER    (200)
    /*
        On met toujours des parenthèses aux #define ce qui donne ainsi l'habitude d'en mettre et permet donc de ne pas les oublier quand c'est vraiment nécessaire
        #define SOMME(a, b)         a+b
        printf("%d\n", 2*SOMME(2, 3))      # 7 au lieu de 10 !!!!
    */
     
    void fonction2(unsigned char px[]) {
        for (size_t i = 0; i < SIZE_BUFFER; i++)
            px[i] = (unsigned char)i;
    }
     
    void affiche(unsigned char px[]) {
        for (size_t i = 0; i < SIZE_BUFFER; i++)
            printf("px[%zu] = %d\n", i, px[i]);
    }
     
    void fonction1() {
        unsigned char x[SIZE_BUFFER];
        fonction2(x);
        affiche(x);
    }
    Voilà. Moins de paramètre donc gain de place et de temps, possibilité de traiter un tableau de taille 200 ou 2000 avec une seule modification, pas de sizeof() potentiellement foireux ; et surtout absolument pas plus de comportement indéterminé que dans ton code (ou que dans mon code d'origine). Après si tu veux on peut rajouter un test sur px à null ou pas à null mais mettre un test dans une fonction void qui donc, de toute façon, ne pourra pas renvoyer d'information à l'appelant je vois pas trop l'utilité...

    Citation Envoyé par sambia39 Voir le message
    Et oui, le langage C ne garantit pas la sécurité des accès mémoire. C'est donc de la responsabilité du développeur de le faire.
    Ben voilà. Tu as tout dit. Alors pourquoi nous présenter un code comme garantissant un contrôle qui est de toute façon impossible ? Il n'y a rien de pire qu'une illusion de sécurité ; c'est comme ça que les accidents arrivent.
    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]

  7. #7
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    551
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 551
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Absolument pas. Enfin, en partant de l'hypothèse standard que le programmeur, censé savoir ce qu'il fait, appelle les fonctions avec un tableau cohérent avec ces dernières (et de toute façon, s'il les appelle avec un tableau incohérent on ne peut pas le vérifier).
    Je comprends ta position, mais elle repose sur une hypothèse risquée : que le programmeur saura toujours fournir un tableau de la bonne taille. En C, peu importe le niveau du programmeur : dès qu’on écrit fonction(unsigned char px[]), ce qui est réellement passé, c’est un pointeur. Et c’est précisément là que réside le problème. Le C ne transporte pas la taille du tableau avec le pointeur, comme tu le soulignes toi-même :

    Citation Envoyé par Sve@r Voir le message
    Il est impossible, totalement impossible, en C, de vérifier qu'un tableau possède bien la taille qu'on lui prête. Et même que mon code d'exemple ne garantit rien en ce sens (rien n'interdit d'appeler fonction2(tab, 5000)). Et là, vas-y, explique-moi comment il se comporte ???
    C’est justement sur ce point précis qu'il faut rendre la taille explicite et que se trouve toute la justification de mon approche. Dans mon approche, l’impact d’une erreur est isolé et le risque de débordement est géré explicitement, même s’il se produit, car la taille devient un paramètre visible. L’appelant doit alors spécifier cette taille de manière consciente. En l’obligeant à la donner, l’erreur devient explicite.

    Ainsi, si le développeur fait un appel comme fonction2(tab, 5000) avec un tableau trop petit , cela devient une erreur évidente dans le code, facile à repérer lors d’une revue ou d’un débogage. En d’autres termes, l’erreur est visible et traçable. Ton approche, elle, ne résout pas le risque de débordement aussi; elle le masque en supposant que l’appelant saura toujours fournir un tableau de la bonne taille.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // Ton approche → Danger silencieux  
    void fonction2(unsigned char px[]) {  // Supposition : px[200] ? px[100] ?  
        for (size_t i = 0; i < 200; i++) px[i] = i;  // UB si taille réelle < 200  
    }  
     
    // Mon approche → Erreur évidente  
    void fonction2(unsigned char px[], size_t taille) {  // Taille explicite  
        for (size_t i = 0; i < taille; i++) px[i] = i;  // Si débordement, c'est l'appelant qui l'a choisi.  
    }

    Dans ton approche, la signature de la fonction void fonction2(unsigned char px[]) ne donne aucune information sur la taille attendue et repose sur une supposition implicite. Si un développeur l’appelle un jour avec un tableau plus petit, le programme écrira en dehors des limites allouées. Ce comportement indéfini peut entraîner une corruption de données, voire un crash, sans que l’erreur ne soit visible au moment de l’appel. En adoptant une approche avec des paramètres en +, les erreurs deviennent explicites plutôt que silencieuses. Cela facilite le débogage, car :

    • les erreurs de débordement pointent directement vers l’appel fautif,
    • il n’est pas nécessaire de réécrire la fonction pour gérer différentes tailles,
    • l’adaptation aux changements de spécifications devient plus simple,
    • le contrat de la fonction est clair dans sa signature


    Et si la philosophie du C est le programmeur c’est se qu'il fait cela n’implique pas de tolérer les débordements silencieux; pour moi la philosophie du C va au-delà du simple "le programmeur sait ce qu'il fait" elle devrait plutôt être comprise comme "donnons au programmeur les outils pour exprimer clairement ses intentions". En rendant la taille explicite, je respecte cette philosophie en contraignant le programmeur à déclarer explicitement ses actions, plutôt que de le laisser s'appuyer sur des suppositions implicites et non vérifiables.

    En relisant attentivement, tu verras que je ne parle pas que de sécurité mais plusd e gestion explicite des erreurs. Dans une approche ou l’erreur de la fonction ici fonction2(tab, 5000) est explicite et traçable, contrairement au débordement silencieux, difficile à détecter. Et justement, à mon sens, le problème du PO ne vient pas d’une simple conversion de type mais d’un dépassement d’index dans un tableau et je vais dans le sens de @Obsidian. Aussi, Le type choisi change beaucoup les effets d'un débordement il faut l'admettre:


    • Avec int px[200] (sur certains anciens matériels sizeof(int) == 2 octets) ainsi 200 éléments × 2 octets = 400 octets. Si on accède à l’index 210, l’adresse écrite est px + (210 × 2) = px + 420 octets. Il y a donc 420 − 400 = 20 éléments * 2 = 40 octets d’écriture après la fin du tableau sur du vieux matos ces 40 octets peuvent tomber dans une zone de RAM non critique ou une variable voisine sans crasher immédiatement (bug silencieux).


    • Pour un char px[200] (sizeof(char) == 1) les 200 éléments × 1 octet = 200 octets. L’index 210 écrit à px + 210 = overflow de 10 octets après la fin. Ces 10 octets atteignent plus rapidement des données critiques sur la pile (adresse de retour, variables locales), ce qui peut écraser une adresse de retour et provoquer un reboot immédiat.


    • Sans oublier les problèmes des cast; un cast mal fait ou un accès qui peux être traité comme int sur un tableau d’unsigned char. car, certains compilateurs comme SDCC ou autres n’appliquent pas les mêmes protections que l’on trouve sur des systèmes exploitations la gestion des accès est très rustique. Et les alignements mémoire imposent que les accès en mémoire soient alignés sur la taille du type. Et donc; écrire "n" bits sur une adresse non alignée peut engendrer des corruptions ou un crash matériel.


    Donc; selon le type, un débordement peut "sauter" au-dessus des zones critiques (un comportement typique d’un bug silencieux avec un int) ou toucher très vite la zone critique et provoquer un crash immédiat avec char. C’est pourquoi à mon sens ils’agit d’un problème d’accès mémoire lié à un index incorrect, et j’insiste sur le fait que passer la taille du tableau à la fonction permet de détecter ce type d’erreur et de l’isoler. (Pour le PO il faut aussi veiller à utiliser le bon type partout et éviter les accès incompatibles).

    Concernant l’utilisation de #define SIZE_BUFFER (200). Cela n’apporte pas réellement de gain en performance ou en mémoire. Cela rend le code rigide : on impose une taille fixe globale, ce qui limite la réutilisation de la fonction; crée une illusion de sécurité, car la fonction ne vérifie pas si le tableau passé correspond réellement à SIZE_BUFFER. Et les #define sont sujets à des erreurs telk que substitution sans typage, de portée globale etc. Vouloir économiser un paramètre au prix de la clarté (et donc de la sûreté) est un compromis dangereux. Mais tu as tes raisons.

    Citation Envoyé par Sve@r Voir le message
    Accessoirement c'est dommage de créer un #define (ça c'est super pour faciliter l'évolution) et de ne pas savoir l'utiliser plus que ça...
    Je te l’accorder , mais en réalité je n’utilise pas ce #define comme une constante universelle, mais comme donnée d’initialisation dans un contexte précis. Et, détail important, si ta macro est une expression il faut des parenthèses ; sinon tu risques des surprises à la macro-expansion.

    Pour conclure selon moi:

    • Ton approche = hypothèse implicite ce tableau fait 200 = risque de crash silencieux .
    • Mon approche = contrat explicite fonction2(tableau, taille) = erreur visible; commise et traçable.


    Et mon but n’est pas d’affirmer qu’avec cette technique on "garantit" un contrôle impossible en C, mais de rendre les erreurs plus visibles, faciliter la maintenance et isoler les problèmes au lieu de les masquer.
    La philosophie du langage C veut que le programmeur soit responsable de la réalisation explicite de ces vérifications

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Je comprends ta position, mais elle repose sur une hypothèse risquée : que le programmeur saura toujours fournir un tableau de la bonne taille....Ton approche, elle, ne résout pas le risque de débordement aussi; elle le masque en supposant que l’appelant saura toujours fournir un tableau de la bonne taille.
    Tout à fait. Tu as parfaitement résumé. C'est très exactement ma position et mon hypothèse. Je pars du principe que le programmeur sait ce qu'il fait et maîtrise entièrement les tableaux qu'il utilise. C'est d'ailleurs un des fondements du C et c'est aussi implicitement écrit dans ta signature.

    Citation Envoyé par sambia39 Voir le message
    Ton approche = hypothèse implicite ce tableau fait 200 = risque de crash silencieux .
    Entièrement d'accord: Mon approche = hypothèse implicite ce tableau fait 200 = risque de UB si le programmeur ne sait pas gérer son tableau. Tant pis, c'est son problème, pas le mien. Celui qui ne sait pas conduire une voiture il ne conduit pas de voiture ; et celui qui ne sait pas gérer son propre tableau il ne gère pas de tableau (il n'a qu'à aller faire du Python, là bas il sera tranquille, les tableaux se gèrent tout seul et il suffit même de réaffecter la variable contenant un tableau à autre chose pour que ledit tableau soit automatiquement nettoyé).

    Citation Envoyé par sambia39 Voir le message
    Mon approche = contrat explicite fonction2(tableau, taille) = erreur visible; commise et traçable.
    Certes, et c'est un argument. Mais pour exprimer ton point de vue, avais-tu besoin en introduction de dire "ce code (le mien) entraîne (verbe impliquant une notion d'inéluctabilité incontournable) un UB" ??? On ne s'élève pas en rabaissant les autres.

    Citation Envoyé par sambia39 Voir le message
    Et, détail important, si ta macro est une expression il faut des parenthèses ; sinon tu risques des surprises à la macro-expansion.
    Oui, c'est écrit dans le commentaire du second code d'exemple (sous la macro) => puisque parfois il faut des parenthèses, moi je mets tout le temps des parenthèses. Ca devrait te plaire puisque tu sembles chercher des moyens d'éviter les erreurs de programmation et que selon moi, cette façon de faire est justement un moyen permettant d'éviter les erreurs de programmation (celui qui met des parenthèses tout le temps ne risque pas de les oublier...)
    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. Réponses: 2
    Dernier message: 02/09/2008, 11h37
  2. [Wincc flexible] Passage d'un pointeur a une fonction Vbs
    Par ren973 dans le forum Automation
    Réponses: 34
    Dernier message: 10/04/2008, 18h29
  3. Réponses: 31
    Dernier message: 31/03/2008, 14h58
  4. Réponses: 12
    Dernier message: 17/07/2007, 08h29
  5. [Syntaxe] problème de passage de type en argument
    Par coyotte507 dans le forum C++
    Réponses: 2
    Dernier message: 25/05/2007, 15h50

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