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.
Aujourd'hui, cours de langage C++. Voila comment mon prof' boucle sur un tableau :
for (int i = 1; i <= N; i++) {
     tabTarger[i – 1] = tabSource[i – 1];
}
PEBKAC.
PEBKAC #9192 proposé par DragaoAzul45 le 31/12/2013 | 41 commentaires | 👍🏽 👎🏽 -161
Avant de voter, j'aimerais savoir ce qui te choque là-dedans.
Commentaire #124028 écrit par Alfred456654 le 31/12/2013 à 09h21 | 👍🏽 👎🏽
Je suppose qu'il pourrait partir de 0 et éviter la soustraction... Chose à mon avis simplifiée par le compilateur, donc strictement équivalente.
Commentaire #124031 écrit par Epok__ le 31/12/2013 à 09h33 | 👍🏽 👎🏽
Le fait que "l'indiçage" du tableau commence à zéro (ce n'est pas le cas de tous les langages) oblige à faire -1 quelque part.
Il est vrai qu'habituellement, on fait -1 sur le nombre d'éléments du tableau pour ne pas avoir à décrémenter l'indice à chaque fois qu'il est utilisé dans la boucle.
Mais, à priori, son code ne devrait pas poser de problème (si N est bien initialisé).
Commentaire #124032 écrit par Picc le 31/12/2013 à 09h35 | 👍🏽 👎🏽
Comme dit sur un PEBKAC précédent, un code non optimisé mais fonctionnel n'est pas un PEBKAC c'est sur que de mettre for i = 0; i < N; i++ serait un peu plus propre mais bon...
Commentaire #124038 écrit par Shadam le 31/12/2013 à 09h48 | 👍🏽 👎🏽
Certes, mais là il s'agit d'un cours, pas d'un code qui a été maintenu pendant 20 ans par 30 personnes différentes, il n'y a pas d'excuses. PEBKAC validé pour ma moi.

P.S. Il ne me semble pas évident que le compilateur réussisse à optimiser ça et que ce ne soit pas au prix de rater une autre optimisation.
Commentaire #124041 écrit par anonymous le 31/12/2013 à 10h16 | 👍🏽 👎🏽
Il s'agit peut-être d'un cours maintenu pendant 20 ans... qui était à l'origine un cours de Pascal ?
Commentaire #124042 écrit par Tharkun le 31/12/2013 à 10h21 | 👍🏽 👎🏽
Les boucles sont en général optimisées par le compilo. Après, ça dépends peut-être du niveau d'optimisation demandé, mais elles sont généralement bien comprises par le compilateur, et ce genre de cas me semble tout à fait apte à être optimisé au cours de l'analyse de la boucle, surtout aussi simple : i n'est utilisé nulle part ailleurs que pour l'indexage des tableaux, càd un pointeur incrémenté à chaque itération...
Commentaire #124043 écrit par Epok__ le 31/12/2013 à 10h24 | 👍🏽 👎🏽
Sans doute une faute de frappe en rédigeant le PEBKAC mais le tableau de destination, il ne sʼappellerait pas plutôt tabTarget ?
Commentaire #124044 écrit par /etc/passwd le 31/12/2013 à 10h31 | 👍🏽 👎🏽
Je parie que c'est pour l'exemple. Il dit on va de 1 à n donc for (i=1;i<=n;i++) mais le tableau va de 0 à n-1.
Le but est d'évaluer les étudiants en regardant quels sont ceux qui vont le simplifier.
Commentaire #124046 écrit par but2ene le 31/12/2013 à 10h42 | 👍🏽 👎🏽
Le bon vieux coup du "C'était pour voir si vous étiez attentifs" ...
Commentaire #124050 écrit par Picc le 31/12/2013 à 10h53 | 👍🏽 👎🏽
Je ne connais pas bien le langage C mais n'était-il pas envisageable d'affecter directement le contenu de tabSource à tabTarguet ?
Commentaire #124053 écrit par vualatele le 31/12/2013 à 11h49 | 👍🏽 👎🏽
J'ai la flemme de tester (et pas fait de C++ depuis des lustres), mais ne pourrait-on pas faire directement tabTarger = tabSource ?
Commentaire #124055 écrit par TD le 31/12/2013 à 11h54 | 👍🏽 👎🏽
pas intuitivement, mais oui avec un memcpy (pour le langage C),

pour C++ ça dépend du type du tableau, dans l'exemple ci dessus ça pourrait être un conteneur de la librairie standart, vector par exemple, auquel cas tu peux utiliser le constructeur par copie, ce qui donne un rendu plus intuitif dans le code.
Commentaire #124056 écrit par yomama le 31/12/2013 à 11h57 | 👍🏽 👎🏽
Le code présenté n'est donc pas un PEBKAC (même si ce n'est peut-être pas le plus optimisé). Je vote donc CTLP.
Commentaire #124057 écrit par vualatele le 31/12/2013 à 12h02 | 👍🏽 👎🏽
Nope, tu te retrouverai avec deux pointeurs qui pointent sur la même mémoire.

Par contre, en C++, mieux vaut utiliser les conteneurs de la STL, et donc profiter de leur constructeur par copie pour ce genre de cas.
Commentaire #124059 écrit par Asdf le 31/12/2013 à 12h16 | 👍🏽 👎🏽
@Shadam : Je suis entièrement d'accord. Ce serait comme dire : il a utilisé i++ au lieu de ++i donc PEBKAC.
C'est stupide.

(Pour l'anecdote, et d'après ce dont je me souviens en C++, ++i est dans le pire des cas aussi rapide que i++, et dans le meilleur des cas, plus rapide. Mais encore une fois, ce n'est pas une optimisation qui va changer la face du monde informatique, on risquerais de gagner quoi, 1 à 2 cycles d'horloge processeur...)
Commentaire #124065 écrit par Raizarachi le 31/12/2013 à 13h35 | 👍🏽 👎🏽
@Raizarachi : i++ (post-incrementation) est différent de ++i (pré-incrementation)

int a = 5, b = 5; 
 int c = ++a; //c vaut 6
 int d = b++; //d vaut 5 
Commentaire #124066 écrit par chipeauteur le 31/12/2013 à 13h47 | 👍🏽 👎🏽
En C aussi ça dépend du type de tableau.
Si tu fait un memcpy d'un tableau long[] dans un short[], par exemple, le résultat risque de ne pas être celui auquel tu t'attend.
Commentaire #124067 écrit par Shirluban le 31/12/2013 à 14h02 | 👍🏽 👎🏽
Personnellement, je valide : si les élèves n'ont pas une réflexion très avancée (du genre "l'prof à écrit ça, alors je met ça"), ou une expérience minimale, ce genre de code les embrouillent complètement. (Oui, il y a du vécu, Loy, le donneur de cours bénévole de son internat ... qui s'arrache violemment les cheveux :p)
Commentaire #124070 écrit par Loy le 31/12/2013 à 14h27 | 👍🏽 👎🏽
@chipeauteur: T'as déclaré 2 variables `a` et `b` alors que tu aurais pu te servir de `a` à chaque fois vu que tu ne changes pas sa valeur, PEBKAC.

Commentaire #124073 écrit par Shadam le 31/12/2013 à 14h35 | 👍🏽 👎🏽
Euh... bah si, il change sa valeur... a et b valent tous deux 6 après leur utilisation respective.
Commentaire #124074 écrit par Epok__ le 31/12/2013 à 14h38 | 👍🏽 👎🏽
Ha bon ? ++a ne change pas a ?

EDIT : Grillé par Epok__
Commentaire #124075 écrit par Picc le 31/12/2013 à 14h41 | 👍🏽 👎🏽
N'utilisons que a, comme préconisé par Shadam :
int a = 5;
 int c = ++a; //c vaut 6
 int d = a++ // d vaut 6 

Et à la fin, a vaut 7 alors que dans mon premier exemple il vallait 6
Commentaire #124076 écrit par chipeauteur le 31/12/2013 à 14h46 | 👍🏽 👎🏽
Epok__ et Picc : c'est épique à notre époque !
Commentaire #124078 écrit par NeMeMoinssePas le 31/12/2013 à 15h05 | 👍🏽 👎🏽
Il me semble que memcpy copie la plage mémoire sans se soucier du type de contenu. Tu lui passe donc un pointeur source, et il le copie vers un pointeur cible. Si tu passe les bons pointeurs et la bonne taille (un simple nbrÉlements * sizeof(type) devrait suffire), je ne vois pas pourquoi il y aurait des problèmes.

À la limite, si les types source et destination n'ont pas la même taille, il pourrait y avoir des problèmes pour des raisons d'endianness en cas de copie élément par élément, mais pas en opérant sur une plage mémoire.

Après, si les types n'ont pas la même taille, faut être sûr de les manipuler correctement, mais c'est souvent utilisé en C : par exemple faire un union entre un entier sur 32 bits et un tableau de 4 octets, pour ensuite utiliser soit la totalité de la valeur, soit un octet particulier.
Commentaire #124080 écrit par Epok__ le 31/12/2013 à 16h19 | 👍🏽 👎🏽
@Picc
Comme tu dis, il faut faire moins quelque part.
Mais on le faisant dans le corps de la boucle, comme ici, une personne en apprentissage risque de passer à côté du fait que les indices de tableaux commencent à 0 en C/C++.
Alors que quand c'est dans le "for", c'est visible tout de suite, même si on ne fait que jeter un coup d'œil rapide sur le code.
Commentaire #124081 écrit par Tharkun le 31/12/2013 à 16h28 | 👍🏽 👎🏽
" il pourrait y avoir des problèmes pour des raisons d'endianness"
Qui a dit que les informaticiens parlaient un jargon incompréhensible ?
Commentaire #124082 écrit par Tharkun le 31/12/2013 à 16h52 | 👍🏽 👎🏽
En français, on parle de boutisme... « gros boutisme » et « petit boutisme »... C'est moche et ça veut rien dire. Je préfère le terme original.
Commentaire #124084 écrit par Epok__ le 31/12/2013 à 18h52 | 👍🏽 👎🏽
Bonne année + 5 minutes.
Commentaire #124092 écrit par ROB (pas loggué) le 01/01/2014 à 00h04 | 👍🏽 👎🏽
Enfin, tout est relatif.
Commentaire #124093 écrit par ROB (pas loggué) le 01/01/2014 à 00h05 | 👍🏽 👎🏽
Bonne année tout le monde!
Commentaire #124094 écrit par Pyrhan le 01/01/2014 à 00h45 | 👍🏽 👎🏽
Bananier et bonne santé à tous !
Commentaire #124095 écrit par Siggy le 01/01/2014 à 03h55 | 👍🏽 👎🏽
Parce que _endianness_ c'est plus parlant, peut-être ? En plus c'est chiant à prononcer ! Boutisme est un calque direct de l'anglais, la seule raison de ne pas l'utiliser c'est ce pédantisme à la con qui refuse depuis une ou deux décennies d'adopter les néologismes du français.
Commentaire #124096 écrit par Dominus Carnufex le 01/01/2014 à 08h32 | 👍🏽 👎🏽
Je ne connait pas le C++, mais il n'y a pas moyen de faire un itérateur avec un foreach?
genre comme en php:

foreach($tabSource as $key => $value) $tabTarget[$key] = $value;
Commentaire #124151 écrit par o4b le 01/01/2014 à 19h59 | 👍🏽 👎🏽
Très bien, alors du coup, je t'attends pour remplacer « cliquer » par « cliqueter » selon les recommandations officielles. On en reparle après.

J'ai découvert le terme « boutisme » sur internet, selon les mêmes recommandations. Jamais personne que je connais n'a employé le terme. Alors oui, utilisons des termes décrétés par des types qui ne sont pas du milieu et n'en connaissent même pas la signification, c'est tellement plus français...

C'est comme « bug » et « bogue »... « Bug » a une signification historique. Mais ça ne fait pas français. Du coup, on préfère recycler un mot qui n'a aucun lien, la « bogue » de châtaigne. Mais au moins, ça fait français.
Commentaire #124161 écrit par Epok__ le 01/01/2014 à 21h45 | 👍🏽 👎🏽
De base foreach n'existe pas en C++.

Et les possibilités pour un faire serait inadapté pour le cas de l'exemple : plus long à codé qu'une boucle for et surement moins efficace.

En C++ je vois 2 options simple :
- la boucle avec la copie pour chaque élément
- si on est sur un tableau de type de base : un gros memcpy.
Commentaire #124185 écrit par Bear'sBeard le 02/01/2014 à 01h16 | 👍🏽 👎🏽
Pas d'itérateur relativement natif comme en java non plus? <troll>Tain, c'est vide et nul le C++</troll>
Commentaire #124233 écrit par o4b le 02/01/2014 à 10h27 | 👍🏽 👎🏽
Jʼai déjà rencontré des programmeurs qui parlaient de « petit Indien » et « gros Indien ». La première fois, ça surprend.
Commentaire #124289 écrit par /etc/passwd le 02/01/2014 à 20h30 | 👍🏽 👎🏽
Joli, un mélange des termes anglais et français, avec une approximation phonique au milieu ! Je crois que j'utiliserai ces termes maintenant.
Commentaire #124290 écrit par Epok__ le 02/01/2014 à 20h40 | 👍🏽 👎🏽
que l'on dise «petit boutien» et «gros boutien» ne me dérange pas puisque cette appellation vient du roman les voyages de gulliver, où je sais plus quel peuple se divise entre «petit boutiens» et «gros boutiens» (respectivement «little endians» et «big endians» en version anglaise), selon que les gens considère qu'il faut manger les œufs à la coque par le gros ou le petit bout.

http://en.wikipedia.org/wiki/Endianness#Etymology
Commentaire #124348 écrit par yomama le 05/01/2014 à 21h24 | 👍🏽 👎🏽
Le code est fonctionnel certes, mais c'est un PEKBAC car c'est de la mauvaise programmation, ce n''est ni logique ni habituel de commencer à 1 au lieu de commencer à 0 pour iterer sur un tableau.

C'est impardonnable pour un prof.
Commentaire #124354 écrit par aaaa le 06/01/2014 à 11h18 | 👍🏽 👎🏽