Bienvenue sur PEBKAC.fr, le site qui recense les anecdotes où l’on se moque des utilisateurs ne maîtrisant pas l’outil informatique. PEBKAC est un acronyme signifiant « Problem Exists Between Keyboard And Chair ».
Le problème se situe entre la chaise et le clavier : soumettez vos histoires, donnez votre avis !
Ce site n'est pas le site original pebkac.fr. Je publie ici la liste des PEBKAC que j'ai pu sauvegarder avant que le site original ne soit mis hors ligne.
En seconde année de licence d'informatique, le professeur de travaux dirigés nous dit :

« Pour le cas où l'utilisateur donnerait un argument négatif à la fonction factorielle, nous pouvons interrompre le programme en la modifiant ainsi : »

int fact(int n) {
  if (n < 0)
    return EXIT_FAILURE;
  […]
}

Pour sa défense, ce n'est pas du tout son domaine, mais ignorer la différence entre return et exit()… PEBKAC.
PEBKAC #9270 proposé par Walbum le 15/01/2014 | 19 commentaires | 👍🏽 👎🏽 -97
Je mise sur un abus de langage sur le "interrompre le programme".
Il me parait plus pertinent de remonter une erreur à l'appelant qui pourra la traiter à plus haut niveau et éventuellement terminer le programme que d'avoir une fonction utilitaire relativement "bas niveaux" qui me tue mon programme au premier appel erroné.
Commentaire #125451 écrit par Bear'sBeard le 15/01/2014 à 17h37 | 👍🏽 👎🏽
Je suis à moitié du même avis.
Effectivement, "exit" n'est pas le mieux ici, mais "return" non plus... le mieux serait un "raise/throw" (selon le langage) pour lever une exception.
Commentaire #125452 écrit par Anonyme le 15/01/2014 à 17h47 | 👍🏽 👎🏽
Vu le PEBKAC précédent, je table sur du C ...
Commentaire #125454 écrit par Noname le 15/01/2014 à 17h54 | 👍🏽 👎🏽
Il s'occupe des travaux dirigés en Informatique mais ce n'est pas son domaine ?
J'ai pas tout compris moi...
Commentaire #125472 écrit par Lnou le 15/01/2014 à 18h40 | 👍🏽 👎🏽
Je choisissais entre les 2 options proposés par l'auteur. De plus comme le dit Noname, il s'agit probablement de C, rentrer dans un système d'exception pour traiter un problème de paramètre invalide dans ce cas me parait clairement de trop.

Et au final la solution peut se régler de manière beaucoup plus simple en acceptant uniquement des entier non signé.
Commentaire #125473 écrit par Bear'sBeard le 15/01/2014 à 18h47 | 👍🏽 👎🏽
Les fonctions sont parfois nommées « sous-programmes », afin de généraliser (cf. assembleur où la notion est très présente car il n'existe pas de notion d'appel de fonction). Il peut s'agir d'un abus de langage.

Ou alors, il pensait réellement que retourner cette valeur interrompait le programme, mais pour un prof, ça me semble vraiment gros...
Commentaire #125482 écrit par Epok__ le 15/01/2014 à 19h18 | 👍🏽 👎🏽
La casse toute majuscule de la variable d'erreur semble effectivement indiquer une valeur préprocesseur selon les conventions du C.
Commentaire #125484 écrit par Epok__ le 15/01/2014 à 19h21 | 👍🏽 👎🏽
@Epok__ : EXIT_FAILURE et EXIT_SUCCESS sont des constantes définies dans stdlib.h valant respectivement 1 et 0.
Commentaire #125492 écrit par BSK le 15/01/2014 à 20h25 | 👍🏽 👎🏽
Oui, c'est courant, et même ultra courant pour les non-permanents (doctorants, ATER, etc.). On te donne des cours à assurer, parfois au dernier moment, parfois sans filet, c'est rarement dans ton domaine d'expertise, ou alors faut avoir pas mal de chance.
Commentaire #125493 écrit par dot le 15/01/2014 à 20h28 | 👍🏽 👎🏽
EXIT_FAILURE est une constante ici. Même si une exception serait plus à propos, le code est juste.
Commentaire #125510 écrit par OzoneGrif le 15/01/2014 à 21h56 | 👍🏽 👎🏽
Bien sûr que le code est juste, mais la façon de spécifier l'erreur ne l'est pas.

Pourquoi ? Parce que EXIT_FAILURE peut très bien être un entier naturel, autrement dit une sortie possible dans le cadre d'une utilisation normale.
Exemple, si EXIT_FAILURE vaut 1, alors comment savoir si fact(1) a fonctionné ou réussi ?

Qu'il soit possible de confondre une sortie correcte et un code d'erreur est inacceptable, la bonne solution dans ce cas serait de renvoyer un nombre négatif (-1).
Commentaire #125519 écrit par Lynix le 15/01/2014 à 23h15 | 👍🏽 👎🏽
Factorielle est definie sur les entiers strictement positif, lui envoyer un nombre inférieur ou égal à 0 n'est donc pas un scénario exceptionnel mais une rupture de contrat de la fonction (on brise sa précondition) et doit donc être traitée par assertion.
@Beat'sBeard : ça ne règle qu'une partie du problème : 0 doit être refusé aussi.
Commentaire #125526 écrit par KsassPeuk le 16/01/2014 à 07h24 | 👍🏽 👎🏽
@KsassPeuk : Factorielle est bien définie en zéro, 0! = 1.
Commentaire #125529 écrit par leafty le 16/01/2014 à 07h34 | 👍🏽 👎🏽
Ou sinon, on prend comme paramètre un unsigned int, et le problème est résolu...
Commentaire #125531 écrit par Epok__ le 16/01/2014 à 08h09 | 👍🏽 👎🏽
@leafty : ça m'apprendra à relire que la moitié de la définition. Ce que j'aime avec les maths c'est qu'ils posent une définition, s'aperçoive que ça leur convient pas et donc rajoute un morceau derrière (pour traiter le cas voulu).
Commentaire #125536 écrit par KsassPeuk le 16/01/2014 à 08h45 | 👍🏽 👎🏽
On ne gère pas un contrat par retour de fonction, ni par exception.
Commentaire #125557 écrit par KsassPeuk le 16/01/2014 à 09h31 | 👍🏽 👎🏽
A noter : si on met juste <= 0, le contrat est insuffisant aussi, puisqu'on ne gère pas l'overflow.
[HS] Faudrait que je fasse un compte un jour ...[/HS]
Commentaire #125563 écrit par KsassPeuk le 16/01/2014 à 09h49 | 👍🏽 👎🏽
La manière standard de faire de la libc (ou en tout cas la version Linux, mais je pense que c'est plus générique) est d'utiliser la variable globale "errno" pour stocker le code d'erreur. C'est pas très pratique, ni très robuste, mais ca marche (plus ou moins)...
Commentaire #125581 écrit par Mufman le 16/01/2014 à 10h41 | 👍🏽 👎🏽
Dans tous les cas, ça ne sera pas reconnu comme une erreur mais comme une valeur de retour de la fonction, donc C'EST indéniablement un PEBKAC.
Commentaire #125659 écrit par Cartman34 le 16/01/2014 à 20h21 | 👍🏽 👎🏽