• [^] # Re: Structure

    Posté par . En réponse au message retourner un pointeur vers un tableau de pointeurs. Évalué à 4.

    Mouais, c'est un débat récurrent. Il y a même un flag à passer à GCC si on veut qu'il nous signale ce genre de choses. Pour autant, je trouve que c'est encore une des nombreuses mesures parties d'un bon sentiment et qui se sont avérées plus pénibles qu'autre chose à l'usage. Il ne faut pas oublier que le propre d'une fonction, en mathématiques, est d'être une expression évaluable et dont la valeur dépend du paramètre. Qu'on utilise les arguments en entrée et en sortie et qu'on utilise le code de retour que comme état du bon déroulement du processus, c'est un paradigme intéressant, certes, mais il s'agit alors de simples procédures, et plus de fonctions à proprement parler.

    Ça commence à devenir franchement lourdingue lorsque ce flag est imposé à la va-vite en entreprise et que ça t'empêche de faire un usage judicieux de tes structures. Le cas d'école que l'on brandit à chaque fois est celui des nombres complexes, bien sûr. Mais de façon similaire, et c'est intéressant parce que c'est un cas vécu, on pourrait parler des timestamps, par exemple.

    J'ai travaillé sur un filtre qui loguait certains événements sous forme d'objets datés avec une « struct timeval » utilisée entre autres par gettimeofday() et qui embarque un nombre de secondes et un nombre de micro-secondes. Au bout d'un moment, pour pouvoir les comparer facilement et traiter les échéances, j'ai fini par écrire une panoplie de fonctions pour pouvoir additionner, soustraire et comparer des durées, ainsi que quelques autres opérations.

    struct timeval timeadd (struct timeval, struct timeval); /* Additionne deux durées */
    struct timeval timesub (struct timeval, struct timeval); /* Soustrait deux durées */
    int timecmp (struct timeval, struct timeval); /* Compare deux durées */
    
    

    ce qui me permettait d'écrire directement des trucs du style :

    if (timecmp(timesub(datefin,datedebut),dureemaximum)>0) action_approriee();
    
    

    Essaie de faire facilement la même chose avec des pointeurs. Tu te retrouves obligé de tout allouer toi-même et décomposer ton calcul. Ensuite, soit tu fais des malloc()/free() en gérant les erreurs éventuelles ce qui, même à l'exécution, est autrement plus long à traiter que huit octets passés dans la pile, soit tu déclares à l'avance des variables locales pour recevoir des résultats et là, dans un cas comme dans l'autre, les résultats se retrouveront dans la pile, avec la conséquence supplémentaire que tes variables auront une existence plus longue que les paramètres et la valeur de retour de chacune de ces fonctions.

    Alors autant je suis le premier à dire qu'il faut s'efforcer autant possible d'être sobre avec la pile (on voit beaucoup de débutants allouer des tableaux d'entiers de 2 Gio) et ne pas l'encombrer pour rien, autant je pense que dans ce genre de cas, aujourd'hui, on peut se permettre de passer des objets jusqu'à une centaine d'octets quand leur taille est fixe, qu'il faut en produire beaucoup et qu'ils sont éphémères.