29 votes

Pourquoi ce code a-t-il encore fonctionné ?

Un vieux code que je viens de trouver :

MLIST * new_mlist_link()
{
    MLIST *new_link = (MLIST * ) malloc(sizeof(MLIST));
    new_link->next  = NULL;
    new_link->mapi  = NULL;
    new_link->result = 0;
}

Elle était appelée pour construire une liste liée, mais j'ai remarqué qu'il n'y avait pas d'instruction :

return new_link;

Même sans l'instruction return, la liste a été construite correctement. Pourquoi cela s'est-il produit ?

Editar: Plate-forme : Mandriva 2009 64bit Linux 2.6.24.7-server GCC 4.2.3-6mnb1

Editar: C'est drôle... ce code a également fonctionné avec succès sur environ 5 installations Linux différentes, toutes des versions/flavors différents, ainsi que sur un Mac.

35voto

Aric TenEyck Points 5434

Sous Windows 32 bits, la plupart du temps, la valeur de retour d'une fonction est laissée dans le registre EAX. Des configurations similaires sont utilisées dans d'autres systèmes d'exploitation, bien que cela soit bien sûr spécifique au compilateur. Cette fonction particulière a vraisemblablement stocké la variable new_link dans ce même emplacement, donc lorsque vous êtes revenu sans retour, la variable dans cet emplacement a été traitée comme la valeur de retour par l'appelant.

Ceci n'est pas portable et très dangereux à faire, mais c'est aussi une des petites choses qui rendent la programmation en C si amusante.

7voto

in70x Points 391

Il est possible qu'il ait simplement utilisé le registre EAX qui stocke normalement la valeur de retour de la dernière fonction appelée. Ce n'est pas du tout une bonne pratique ! Le comportement pour ce genre de choses est indéfini Mais c'est cool de voir que ça marche ;-)

5voto

WhirlWind Points 8305

C'est essentiellement de la chance ; apparemment, le compilateur a placé new_link au même endroit qu'une valeur retournée.

5voto

Georg Fritzsche Points 59185

Pour éviter ce problème, utilisez :

-Wreturn-type :

Avertir lorsqu'une fonction est définie avec un type de retour qui a la valeur int par défaut. Avertir également de toute déclaration de retour sans valeur de retour dans une fonction dont le type de retour n'est pas void (tomber à la fin du corps de la fonction est considéré comme un retour sans valeur), et d'une déclaration de retour avec une expression dans une fonction dont le type de retour est void.

-Werror=return-type pour transformer ce qui précède en une erreur :

Transforme l'avertissement spécifié en erreur. Le spécificateur d'un avertissement est ajouté, par exemple -Werror=switch transforme les avertissements contrôlés par -Wswitch en erreurs. Ce commutateur prend une forme négative, à utiliser pour annuler -Werror pour des avertissements spécifiques, par exemple -Wno-error=switch fait que les avertissements de -Wswitch ne sont pas des erreurs, même lorsque -Werror est en vigueur. Vous pouvez utiliser l'option -fdiagnostics-show-option pour faire modifier chaque avertissement contrôlable avec l'option qui le contrôle, afin de déterminer ce qu'il faut utiliser avec cette option.

(de Options d'alerte des CCG )

1voto

el.pescado Points 7960

Cela fonctionne par coïncidence. Vous ne devriez pas compter sur ça.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X