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 :

Style de C particulièrement opaque


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    codeur amateur
    Inscrit en
    Avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : codeur amateur

    Informations forums :
    Inscription : Avril 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Style de C particulièrement opaque
    Bonjour, simple programmeur en C pour des développements modestes, j'ai trouvé en étudiant le source d'un programme de minimisation un style de programmation très étrange, avec des instructions quasiment absurdes comme:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          double rw[10000],pf[10000];
          double f[10],g[1000],x[1000],xl[1000],xu[1000],param[12];
         ......
          fonc(..,&*f,&*g,&*x,&*xl,&*xu,....)

    et aussi

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       if (*g != *g) {
       ......
        }

    La raison de telles instructions syntaxiquement correctes me semble très obscure, et pourtant, l'insertion de tests sur l'expression (*g != *g) montre que le résultat n'est pas toujours faux.
    Existe-t-il une explication de ce comportement?
    Par ailleurs, le programme se compile et fonctionne correctement, mais son analyse est un défi.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 559
    Points
    10 559
    Par défaut
    if (*g != *g) Non c'est logique : comme il déférence des pointeurs tableaux, il compare la première case dudit tableau.
    Mais comme ce sont des doubles, les comparaisons sont inexactes (je te laisse chercher comment tester 2 flottants)

    Édit: mais c'est la même variable qu'on teste


    Et &*f,&*g,&*x,&*xl,&*xu: il faudrait vérifier avec des %p , mais je dirais qu'il prend l'adresse de la première case des tableaux

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 566
    Points : 7 652
    Points
    7 652
    Par défaut
    Bonjour,

    le test ( *g != *g ) peut être vrai! Si g pointe sur une valeur quiet NaN.
    NaN a la particularité d'être différent de tout nombre y compris de lui-même!

    Quant à &*f ou &f[0], comme f est un tableau cela désigne le début du tableau est a le type double*.
    Alors que f, désigne aussi le début du tableau mais a le type double(*)[10].
    En C, je ne vois pas l'intérêt de distinguer ces cas. En C++, cela peut servir lors de résolutions de template.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    codeur amateur
    Inscrit en
    Avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : codeur amateur

    Informations forums :
    Inscription : Avril 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Oui mais...
    Merci pour la réponse, mais dans la comparaison en question, quel que soit l'élément pris, qui en l'occurrence est normalement le contenu de l'adresse mémoire g, on compare une chose à elle même car l'expression ne modifie pas le contenu de g, donc que puisse être vraie me reste incompréhensible.
    Quant à , elle correspond effectivement à x, je me demandais seulement le pourquoi d'une telle expression, notamment si ce n'est pas une transcription "automatique" en C provenant d'un autre source ou d'un générateur de code?


    Citation Envoyé par foetus Voir le message
    if (*g != *g) Non c'est logique : comme il déférence des pointeurs tableaux, il compare la première case dudit tableau.
    Mais comme ce sont des doubles, les comparaisons sont inexactes (je te laisse chercher comment tester 2 flottants)


    Et &*f,&*g,&*x,&*xl,&*xu: il faudrait vérifier avec des %p , mais je dirais qu'il prend l'adresse de la première case des tableaux

  5. #5
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 474
    Points : 6 119
    Points
    6 119
    Par défaut
    Bonjour,

    En C, si x est un tableau, passer en argument x ou &x[0], c'est la même chose pour le compilateur, mais pas forcément pour le lecteur.
    Si je vois un argument &x[0], je m'attends à ce que la fonction ne travaille qu'avec le premier élément du tableau et ignore les autres.
    Si je vois un argument x, j'ai plus tendance à penser que la fonction ne va pas se contenter du premier élément.

    &*x, par contre, je ne sais pas. Je pense que c'est une convention propre à l'auteur du code. Est-ce que la fonction ne prend en compte que le premier élément ? Si oui, alors &*x est utilisé comme une forme plus concise de &x[0]. Sinon, je ne sais pas.

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    codeur amateur
    Inscrit en
    Avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : codeur amateur

    Informations forums :
    Inscription : Avril 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Désolé de ne pas répondre dans l'ordre...
    Voici la routine qui contient le tets en question, avec mes ajouts:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    integer i304_(doublereal *g)
    {
        /* System generated locals */
        integer ret_val;
     
        ret_val = 0;
    fprintf(stdout,"########### DANS i304_1  : *g %x, g %p  ###########\n",*g,g);
    fprintf(stdout,"########### DANS i304_2  : (*g != *g) %x    ###########\n",(*g != *g));
        if (*g != *g) {
     
        ........
    Le détail de mes sorties de test donne :

    |#### ARGUMENTS APPEL I304_ E ####
    |doublereal*g &l[1] : nan , 00a070a8, 10514600
    |#### ARGUMENTS FIN ####

    ########### DANS i304_1 : *g 0, g fff80000 ###########
    ########### DANS i304_2 : (*g != *g) 1 ###########

    Le résultat de la comparaison est effectivement vraie lorsque *g est affiché à nan du moins en format %e, en format %x il vaut 0.
    J'ignorais les propriétés particulières de cette valeur nan (quand j'ai appris la programmation, elle n'existait pas. d'où des plantages pur et dur).
    Est-ce une manière orthodoxe de coder ainsi ou aux bordures de la norme?
    En tout cas merci pour cette information.



    Citation Envoyé par dalfab Voir le message
    Bonjour,

    le test ( *g != *g ) peut être vrai! Si g pointe sur une valeur quiet NaN.
    NaN a la particularité d'être différent de tout nombre y compris de lui-même!

    Quant à &*f ou &f[0], comme f est un tableau cela désigne le début du tableau est a le type double*.
    Alors que f, désigne aussi le début du tableau mais a le type double(*)[10].
    En C, je ne vois pas l'intérêt de distinguer ces cas. En C++, cela peut servir lors de résolutions de template.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 631
    Points : 10 559
    Points
    10 559
    Par défaut
    Citation Envoyé par arsinuline Voir le message
    Est-ce une manière orthodoxe de coder ainsi ou aux bordures de la norme?
    Tu as raison en disant que tester la même variable cela doit être vrai puisqu'il n'y a pas de modification (que ce soit une comparaison binaire ou flottante)

    Sinon pour ta question, pourquoi ne pas envisager un test pour tester les NaN ?

    D'après wiki NaN (<- lien), c'est dans la norme:
    Cela conduit même à ce que la comparaison « NaN==NaN » (« == » signifie « est-ce que ces valeurs sont égales ? ») donne la réponse « faux ». C'est la seule valeur ayant cette propriété (même l'infini, selon la norme IEEE 754, donne « vrai » pour la requête « Inf==Inf »).

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    codeur amateur
    Inscrit en
    Avril 2017
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : codeur amateur

    Informations forums :
    Inscription : Avril 2017
    Messages : 4
    Points : 1
    Points
    1
    Par défaut affaire règlée
    Le fondement logique de cette norme semble être de dire que deux entités non définies ne peuvent être identiques, ce qui est discutable, elles sont donc différentes, mais en fait on a déplacé le problème, car syntaxiquement on compare une entité à elle même, un compilateur intelligent ne devrait pas laisser passer cela.
    Il est probable que le confort apporté par la tolérance à l'erreur, qui consiste à traiter des entités mathématiquement non définies, conduit à des situations du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a == a est faux si a=nan
    .
    Mais il est vrai que le bout de code que j'incrimine est très certainement le résultat d'un traducteur automatique Fortran -> C.


    D'après wiki NaN (<- lien), c'est dans la norme:[/QUOTE]

Discussions similaires

  1. [VB6] Combiner 2 styles avec MSChart
    Par khany dans le forum VB 6 et antérieur
    Réponses: 8
    Dernier message: 29/04/2003, 09h30
  2. Cherche Fonction du style replace...
    Par sdchamplas dans le forum Langage SQL
    Réponses: 4
    Dernier message: 31/03/2003, 13h54
  3. Etude des "styles" de programmation
    Par RiRi51 dans le forum Langages de programmation
    Réponses: 5
    Dernier message: 12/03/2003, 19h50
  4. feuille de style generale
    Par Manu_Just dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 11/03/2003, 10h06
  5. Rattacher une feuille de style a un XML existant
    Par aour dans le forum XML/XSL et SOAP
    Réponses: 5
    Dernier message: 08/10/2002, 22h07

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