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 :

Philosophie du langage c "Programmation destructive" et optimisation


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut Philosophie du langage c "Programmation destructive" et optimisation
    Bonjour,

    J'ai deux questions.
    La première sur la programmation destructive, l'autre sur l'emploi de fonctions imbriquée.

    1.
    En lisant un tuto sur les listes chainée, l'auteur précise que toutes ses fonctions sont de types VOID car d'après la philosophie du langage C, celui ci se doit d’être destructif.
    Je peux comprendre si l'on travaille sur de très grosses listes (par ex) ou que l'on ne dispose pas d'un espace mémoire important, mais n'est il pas mieux de faire le contraire justement quand on dispose de l'espace ou que l'on sait que l'on ne travaillera pas sur des listes énormes??

    Cela me semble être plus prudent de ne pas "perdre" ou de modifier directement ses variables que l'inverse??!


    2.
    Toujours dans le même tuto, l'auteur dit qu'il vaut mieux éviter l'emploi de fonctions imbriquées.
    De nouveau, je pensais qu'il valait mieux écrire de petite fonctions que l'on peut appeler souvent dans d'autres fonctions, que de réécrire le même bout de code plusieurs fois un peu partout.
    La aussi, je comprend l'idée que l'auteur veut faire passer (je crois), mais a partir de quel moment, ou de quel "lourdeur" du prg parle t on la??

    Merci d'avance de m’éclairer sur ces deux point

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    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 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    1. programmation destructive?
    Je pratique (et enseigne) le C depuis quelques années. Mais je ne comprends pas bien le concept de programmation destructive que tu commentes.
    Que faut-il faire de ses variables calculées ?
    a) si on doit s'en resservir plus tard, il semble logique de les conserver.
    b) si on n'en a plus besoin, il faut les détruire, et ce rapidement.
    c) il peut y avoir des exceptions au cas (a), mais pas au cas (b)
    c.1) conserver une donnée calculée qui pourrait évoluer en fonction du contexte, peut être moins robuste que de la régénérer à la demande.
    c.2) conserver une donnée facile à re-générer peut alourdir inutilement un code (même si elle est de petite taille) car plus il y a d'instances dans un code à un moment, plus il y a risque d'incohérences (surtout dans un système temps réel), il convient donc en effet de se débarrasser de tout ce qui ne sert pas.
    Mais supprimer une donnée que l'on a calculée alors qu'elle peut resservir, ne peut pas être une philosophie.

    2. éviter l'emploi de fonction imbriquées?
    Il est vrai qu'avoir une fonction de 3 lignes qui appelle une fonction de 3 lignes qui appelle une fonction de ... peut être contre productif.
    Un découpage "intelligent" sans fonction trop longue est la seule règle à connaître. Le seul critère est la clarté, si les imbrications correspondent à une logique claire, il n'y a aucun intérêt à s'en passer. Si le problème est l'optimisation (car un appel de fonction coûte), il suffit que les fonctions imbriquées et courtes soient définie inline pour produire un code à la fois clair et optimisé.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    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 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Dunkhan Voir le message
    ses fonctions sont de types VOID
    Une fonction n'a pas de type Tu parles du retour ou des paramètres ?

    Sinon je vois mal le rapport entre void (la généricité) et la destruction
    À moins de faire des pointeurs opaques afin de forcer les programmateurs à coder/ utiliser des fonctions d'initialisation et de destruction.
    Forcer, pour être sûr qu'il n'y a pas de fuites de mémoire parce le programmateur peut penser qu'un simple malloc suffi.


    Et avec les fonctions imbriquées, il y a soit
    • un problème de performance. Chaque appel de fonction est coûteux (sauvegarde/ rechargement du contexte)
    • un problème de pile. Il faut maîtriser la récursion

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 54
    Points : 32
    Points
    32
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Bonjour,

    1. programmation destructive?
    Je pratique (et enseigne) le C depuis quelques années. Mais je ne comprends pas bien le concept de programmation destructive que tu commentes.
    Que faut-il faire de ses variables calculées ?
    a) si on doit s'en resservir plus tard, il semble logique de les conserver.
    b) si on n'en a plus besoin, il faut les détruire, et ce rapidement.
    c) il peut y avoir des exceptions au cas (a), mais pas au cas (b)
    c.1) conserver une donnée calculée qui pourrait évoluer en fonction du contexte, peut être moins robuste que de la régénérer à la demande.
    c.2) conserver une donnée facile à re-générer peut alourdir inutilement un code (même si elle est de petite taille) car plus il y a d'instances dans un code à un moment, plus il y a risque d'incohérences (surtout dans un système temps réel), il convient donc en effet de se débarrasser de tout ce qui ne sert pas.
    Mais supprimer une donnée que l'on a calculée alors qu'elle peut resservir, ne peut pas être une philosophie.
    J'aurai du etre plus clair dans mes explications.

    Le tuto porte sur des listes chainées circulaire (ca n'a pas bcp d'importance en fait).
    Ce que l'auteur du tuto voulait dire par destructive, c'est d'utiliser des pointeurs au lieu de passer une copie et de retourner une liste dans la fonction (dans ce cas ci).

    Retour des fonctions

    Une fonction modifiant un objet est dite "destructive". Les fonctions de modification de liste proposées ci-dessus sont toutes destructives, en accord avec la philosophie du langage C. C'est pourquoi le type de retour est void.
    Ma question en fait portait sur le fait que je pensais qu'il était plus sécurisé de travailler sur des copies dans une fonction et de retourner l'objet, la variable, (etc), plutôt que de travailler directement sur l'objet lui même. Si un malloc plante, si un pointeur est mal définis, etc.. au moins on ne "casse" pas l'objet, la variable, on peut faire un log de l'erreur, le prg ne plante pas(??)..
    Et j’étais étonné de voir que l'auteur suggérais que la "philosophie du C était destructive.



    Citation Envoyé par dalfab Voir le message
    2. éviter l'emploi de fonction imbriquées?
    Il est vrai qu'avoir une fonction de 3 lignes qui appelle une fonction de 3 lignes qui appelle une fonction de ... peut être contre productif.
    Un découpage "intelligent" sans fonction trop longue est la seule règle à connaître. Le seul critère est la clarté, si les imbrications correspondent à une logique claire, il n'y a aucun intérêt à s'en passer. Si le problème est l'optimisation (car un appel de fonction coûte), il suffit que les fonctions imbriquées et courtes soient définie inline pour produire un code à la fois clair et optimisé.
    Toujours dans l'optique de mon code sur les listes chainée, dans un autre tuto, l'auteur utilise des fonctions très simple pour savoir si une liste est vide par ex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /**
    * Retourne une DListe vide
    * @return Une nouvelle DListe
    */
    DList new_dlist(void)
    {
    	return NULL;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /**
    * Teste si une DListe est vide
    * @param li La DListe
    * @return true si la DListe ne contient pas d'éléments, false sinon
    */
    Bool is_empty_dlist(DList li)
    {
    	if(li == NULL)
    		return true;
     
    	return false;
    }
    La fonction is_empty_dlist(DList li) est appelé quasi dans toutes les autres fonctions pour tester si la liste existe avant de faire quoi que ce soit dessus (ajout/suppression de données ou de maillon par ex)..
    La question, c'est "est ce que c'est conseillé"?? ou bien est qu'il vaut mieux code le test directement dans chaque fonction afin d'éviter justement l'effet de fonctions imbriquée??
    Ou dans ce cas ci, une fonction "inline" serait justifiée??



    Citation Envoyé par foetus Voir le message
    Une fonction n'a pas de type Tu parles du retour ou des paramètres ?

    Sinon je vois mal le rapport entre void (la généricité) et la destruction
    À moins de faire des pointeurs opaques afin de forcer les programmateurs à coder/ utiliser des fonctions d'initialisation et de destruction.
    Forcer, pour être sûr qu'il n'y a pas de fuites de mémoire parce le programmateur peut penser qu'un simple malloc suffi.


    Et avec les fonctions imbriquées, il y a soit
    • un problème de performance. Chaque appel de fonction est coûteux (sauvegarde/ rechargement du contexte)
    • un problème de pile. Il faut maîtriser la récursion
    Je parlais bien du type de retour, et non pas de la fonction.. j'en suis toujours au début et je n'utilise pas encore bien le vocabulaire ad hoc

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Dunkhan Voir le message
    Si un malloc plante, si un pointeur est mal définis, etc.. au moins on ne "casse" pas l'objet, la variable, on peut faire un log de l'erreur, le prg ne plante pas(??)..
    Je ne suis pas certain d'avoir saisi : cela n'a pas grand chose à voir avec le fait de passer l'objet en référence constante ou non constante. Dans les deux cas tu peux (et dois) le laisser inchangé si une erreur survient, en ne le modifiant que lorsque toutes les opérations qui pouvaient échouer ont été réalisées.

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