Partage
  • Partager sur Facebook
  • Partager sur Twitter

Excellent cours de Mathieu Nébra pour le C++

C++

Sujet résolu
22 mars 2017 à 16:07:19

Bonjour

cela fait quelques mois que je travaille activement sur le cours de Mathieu Nébra, et même s'il n'est pas parfait, il m'a énormément fait progresser.

J'ai compris des notions que je n'avais pas comprises avec d'autres cours.

J'avais ouvert un fil, et avais eu des réponses pas toujours très cools, et j'ai persisté et signé pour dire merci à Mathieu. On a pu caractériser mon propos d'obtu.... mais à force de chercher le cours parfait, on finit par ne plus rien faire. C'est un grand problème que beaucoup ont. J'ai décidé de ne pas m'arrêter à cela, et j'ai eu raison. Même si j'ai encore beaucoup à apprendre, j'ai déjà beaucoup progressé.

Et j'aurai encore des questions sur le forum évidemment. Ce cours explique par exemple très proprement ce qu'est un pointeur.

Au lieu de chercher la petite bête dans les petits trucs qui ne vont pas, il suffit de faire des recherches par soi-même sur youtube, internet quand on ne comprend pas.

Et si pour certains il y a tant de fautes, et bien qu'à la place de critiquer de cours de Mathieu Nébra, ils envoient un correctif à openclassrooms depuis le temps qu'ils critiquent.

Poiur compléter le cours de Mathieu, il y a des youtubers comme "ProgrammingKnowledge" qui font des superbers vidéos qui peuvent nous aider.

Je suis vraiment content du cours de Mathieu. Quand on veut acquérir de bonnes bases, ce cours est excellent.

Et ce n'est pas parce que on a écrit "using namespace std; " dans un fichier, qu'il y a cata. Ok, c'est vrai, c'est pas optimal dans certains cas, mais on ne devient pas expert du jour au lendemain ....

Amitiés à Gbdivers, LordCasque, openclassrooms, Koala1 et autres intervenants du fil de l'époque

Au passage Gbdivers, j'ai été sur ta page sur C++/QT , et tu fais du bon travail.

-
Edité par pseudo-simple 22 mars 2017 à 16:08:29

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:15:03

Ah! toi tu viens pour te faire taper ! Certains vont se jeter sur toi comme une meute de chien sur un steack ! :lol:  

Mais je vais mettre tout le monde d'accord ! Voici la vraie syntaxe du C++ :

shared_ptr<truc>** p = (shared_ptr<truc>**)malloc(10*sizeof(shared_ptr<truc>*));
p[0] = new shared_ptr<truc>;



  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

22 mars 2017 à 16:29:18

Fvirtman a écrit:

Ah! toi tu viens pour te faire taper ! Certains vont se jeter sur toi comme une meute de chien sur un steack ! :lol:  

Mais je vais mettre tout le monde d'accord ! Voici la vraie syntaxe du C++ :

shared_ptr<truc>** p = (shared_ptr<truc>**)malloc(10*sizeof(shared_ptr<truc>*));
p[0] = new shared_ptr<truc>;



Ça manque de void* et de placement new tout ça.

  • Partager sur Facebook
  • Partager sur Twitter
Pony : Un langage à acteurs sûr et performant
22 mars 2017 à 16:30:45

Heu ....

Ce n'est pas qu'on recherche le cours parfais, mais il faut l'avouer, le cours de Mathieu Nebra est aujourd'hui une catastrophe, et ce n'est pas la seul présence de petits détails malencontreux qui fait dire cela.

Son cours etait (note l'utilisation de la forme passive) à peut près correcte jusqu'en 2011, depuis, une norme est passée l'invalidant completement.

Quand aux mises à jour, si le staff d'OC lit ce forum, ils brillent par leur absence de réaction.

Tu as progressé, certes, malheureusement, ce n'est pas sur la bonne voie, il va te faloir maintenant désapprendre ce que tu as appris pour te mettre à jour, et croit moi, c'est tout sauf facile.

-
Edité par Deedolith 22 mars 2017 à 16:46:04

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:35:00

Praetonus a écrit:

Fvirtman a écrit:

Ah! toi tu viens pour te faire taper ! Certains vont se jeter sur toi comme une meute de chien sur un steack ! :lol:  

Mais je vais mettre tout le monde d'accord ! Voici la vraie syntaxe du C++ :

shared_ptr<truc>** p = (shared_ptr<truc>**)malloc(10*sizeof(shared_ptr<truc>*));
p[0] = new shared_ptr<truc>;



Ça manque de void* et de placement new tout ça.

Bof, du moment que ça compile... :)

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:37:50

Cher Fvirtman,

 j'ai beaucoup aimé ta note note d'humour. Merci pour ton commentaire sympa.

Meilleurs sentiments

Merci aux autres aussi pour leurs commentaires sympas

"du moment que ça compile" : lol ...

@Deedolith : avant de désapprendre, il faut apprendre  ))

J'ai déjà fait de belles choses grâce à ce cours.

Ce cours , à quelques petites erreurs, est vraiment en phase avec des codes très performants.

Si vous avez des preuves concrètes de choses qui ne vont pas dans son cours, vous pouvez les lister ici

je propose de faire dans ce fil, un catalogue de toutes les choses qui ne vont pas dans le cours.

Ainsi, nous aurons un fil qui concentrera tout ce qui DOIT amélioré, et cela bénéficiera à openclassrooms.com ainsi qu'aux futurs lecteurs d'openclassrooms

Que chacun mette ci-après les passages qui doivent impérativement être corrigés

-
Edité par pseudo-simple 22 mars 2017 à 16:47:55

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:46:12

Autant ne pas désapprendre, c'est encore mieux.

Serieusement, entre les 2 functions ci-dessous, mon choix est fait !

int testAlloc()
{
    int* valueA;
    int* valueB;
    try
    {
        valueA = new int;
        try
        {
            *valueA = 10;
            valueB = new int;
            *valueB = 5;
        }
        catch (std::exception const& e)
        {
            delete valueA;
            throw;
        }
    }
    catch (std::exception const& e)
    {
        throw;
    }
    int ret = *valueA + *valueB;
    delete valueB;
    delete valueA;
    return ret;
}

int testAlloc()
{
    std::unique_ptr<int> valueA = std::make_unique(10);
    std::unique_ptr<int> valueB = std::make_unique(5);
    return *valueA + *valueB;
}

-
Edité par Deedolith 22 mars 2017 à 16:50:07

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:48:58

Il manque un ou deux goto pour que ce code soit au top.

  • Partager sur Facebook
  • Partager sur Twitter

git is great because Linus did it, mercurial is better because he didn't.

22 mars 2017 à 16:49:35

Deedolith a écrit:

Autant ne pas désapprendre, c'est encore mieux.

Serieusement, entre les 2 functions ci-dessous, mon choix est fait !

int testAlloc()
{
    int* valueA;
    int* valueB;
    try
    {
        valueA = new int;
        try
        {
            *valueA = 10;
            valueB = new int;
            *valueB = 5;
        }
        catch (std::exception const& e)
        {
            delete valueA;
            throw;
        }
    }
    catch (std::exception const& e)
    {
        throw
    }
    int ret = *valueA + *valueB;
    delete valueB;
    delete valueA;
    return ret;
}

int testAlloc()
{
    std::unique_ptr<int> valueA = std::make_unique(10);
    std::unique_ptr<int> valueB = std::make_unique(5);
    return *valueA + *valueB;
}

C'est sur, sauf quand comme moi tu programmes et vend des librairies, et que certains clients refusent de voir du code C++11, parce que "ça tourne sur leur vieux compilo et qu'ils ne veulent pas changer", et que, comme ces clients sont beaucoup plus gros que nous, ben on ne peux que se courber et dire "oui monsieur, on va continuer en C++ 98 ou 03 encore quelques années .... " :(
  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

22 mars 2017 à 16:51:33

Deedolith, tu as l'air très fort en C/C++

A quel passage du cours de Mathieu fais-tu référence ?

Es-tu sûr qu'il s'agit de son cours de C++ ?

Car il a aussi fait un cours de C qui est vraiment un autre cours , d'après ce que j'ai pu voir.

Pour augmenter ma culture, cela m'intéresserait de comprendre l'intérêt de ton code.

Pour être honnête, je ne connais pas les fonctions throw, try, catch (ainsi que unique_ptr et make_unique), peux-tu me dire comment le premier code à rallonge fonctionne ?

Merci

Cordialement

-
Edité par pseudo-simple 22 mars 2017 à 16:56:34

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 16:51:52

Sujet certes polémique, mais effectivement intéressant !

Je suis parfaitement d'accord, avec un peu de recul et le centième d'expérience des pros du forum, sur le fait que le cours enseigne certaines mauvaises pratiques, et qu'il paraît ensuite assez déroutant de s'entendre dire "c'est n'importe quoi".

Toutefois, je suis d'accord avec Yes, man sur un point : beaucoup de monde a appris énormément de choses grâce à ce cours. Et dans le monde de l'industrie et des éditeurs de logiciels, je ne suis qu'à mon premier emploi et un stage de fin d'études dans le domaine, mais à chaque fois, les gens m'ont regardé avec des yeux ronds et incrédulité quand je leur ai parlé de pointeurs intelligents et autres merveilles (pas de sarcasme, je comprends que ces choses là sont vraiment intéressantes et méritent d'être de plus en plus utilisées)... "On n'a jamais utilisé ça ici, et ça fonctionne... Et puis on va pas recoder ce qui est en opération, maintenance, support depuis 15 ans..."

Donc je suis d'accord, il faut se mettre à jour, apprendre les nouvelles normes, c'est très enrichissant et il y a toujours de bonnes raisons derrière ces changements de pratique et d'utilisation. Mais comme pour beaucoup de choses, il faut faire le compromis entre la norme et l'usage... Et l'usage, n'est pas aujourd'hui massivement pour le C++11 (encore moins le 14, et le 17, n'en parlons pas) dans l'industrie "traditionnelle", dans le monde de la simulation, de l'aéronautique... pour ce qui m'a été donné de voir par exemple.

  • Partager sur Facebook
  • Partager sur Twitter
May The Force Be With You !
22 mars 2017 à 16:56:29

Prends un peu de recul.

A ton avis, est-ce que dans cette boite, dans 10 ans, on dira

"écoute, on programme en C++98 depuis 25 ans et on s'en porte pas plus mal, c'est pas maintenant qu'on va passer à C++11 et encore moins à un langage plus récent"

 ça te parait possible ?

 A ton avis, les nouveautés de C++, elles ont été introduites pour quoi, sinon  faciliter l'écriture et la maintenance des programmes et donc diminuer les coûts ?

-
Edité par michelbillaud 22 mars 2017 à 16:59:37

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 17:03:20

michelbillaud a écrit:

Prends un peu de recul.

A ton avis, est-ce que dans cette boite, dans 10 ans, on dira

"écoute, on programme en C++98 depuis 25 ans et on s'en porte pas plus mal, c'est pas maintenant qu'on va passer à C++11 et encore moins à un langage plus récent"

 ça te parait possible ?

-
Edité par michelbillaud il y a moins de 30s


En ce qui concerne mon cas, je sais qu'on va devoir se taper une compatibilité C++98 pendant encore de nombreuses années, à cause surtout des clients qui ne veulent pas bouger, mais également pas mal de monde qui ont été formés il y a 20 ans et qui ne veulent pas bouger non plus...

Donc ça va évoluer, mais douuuuuucement. douuuuucement .....  Vraiment vraimen doucement....

En tout cas, pour tous les projets nécessitait d'être maintenus à travers le temps.

Sais tu qu'il y encore peu, on avait encore des clients qui voulaient des librairies pour Visual C++ 6 ?!!! (sorti quand, en 1998 ?)

Les derniers ont ENFIN fini par changer.... Il y a peu !!!

-
Edité par Fvirtman 22 mars 2017 à 17:03:52

  • Partager sur Facebook
  • Partager sur Twitter

Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

22 mars 2017 à 17:06:44

@YES, man:
je ne fais référence au aucun "passage" particulier, mais l'un des thème abordé. En l'occurence (ca aurait du te sauter au yeux): Les allocations dynamiques.

@Manu:
L'usage est malheureusement gouverné par entre autre les contraintes et considérations budgétaires, 2 elements sur lequels le programmeur n'a pas forcément contrôle.
Par contre, si l'occasion t'es présentée de pouvoir utiliser les dernières normes, surtout ne te prives pas.

PS: Le fait que "ca marche" ne veut pas dire que c'est correcte.

-
Edité par Deedolith 22 mars 2017 à 17:11:23

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 17:09:12

Deedolith a écrit:

@YES, man:
je ne fais référence au aucun "passage" particulier, mais l'un des thème abordé. En l'occurence (ca aurait du te sauter au yeux): Les allocations dynamiques.

@Manu:
L'usage est malheureusement gouverné par entre autre les contraintes et considérations budgétaires, 2 elements sur lequels le programmeur n'a pas forcément contrôle.
Par contre, si l'occasion t'es présentée de pouvoir utiliser les dernières normes, surtout ne te prives pas.


On ne peut plus d'accord vu comme ça :)

Malheureusement, pas simple, surtout en débutant d'utiliser des choses nouvelles, surtout sans beaucoup d'occasion de les pratiquer du coup, par la force des choses... mais je suis d'accord, un peu d'autoformation et tenter d'inclure progressivement les bonnes pratiques actuelles autant que possible !

-
Edité par Manu310 22 mars 2017 à 17:09:36

  • Partager sur Facebook
  • Partager sur Twitter
May The Force Be With You !
22 mars 2017 à 17:17:17

Je ne sous-estime pas le poids de l'existant : nous avons plein d'offres proposant, dans de grandes sociétés de service dont je tairai le nom, des postes pour de la maintenance corrective/évolutive de Cobol bancaire, sur des applis qui remontent aux années 70-80 (et n'ont cessé d'évoluer depuis), et qu'il faut bien maintenir. On cherche des programmeurs compétents.

Et la techno reste Cobol 85, sans les objets introduits en Cobol 2000. L'explication : Cobol 85 convient très bien pour ce qu'on en a fait, et le parc applicatif est tellement énorme (et critique) qu'on n'envisage pas de tout reconcevoir. Par ailleurs une simple traduction automatique vers un autre langage ne donnerait au mieux que des programmes qui font la même chose, donc ne marchent pas mieux, mais plus difficiles à maintenir. Difficile à justifier.

Mais bon, c'est pas pour développer de nouvelles applis. Tout ça pour dire qu'il reste des niches pour les dinosaures.

-
Edité par michelbillaud 22 mars 2017 à 17:19:25

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 17:17:24

YES, man a écrit:

Si vous avez des preuves concrètes de choses qui ne vont pas dans son cours, vous pouvez les lister ici

Pitié quoi, ça a déjà été fait maintes fois sur le forum. Il y a même un post de blog qui résume la plupart des idées, et encore il manque des choses :

http://informaticienzero.com/c-avec-openclassrooms-ou-comment-perdre-son-temps/

Il y a même une liste de lien en bas.

Un exemple symptomatique des trucs odieux que ça contient : https://openclassrooms.com/forum/sujet/erreur-heritage-poo#message-88917734. Et j'insiste : cet exemple est tiré du "cours".

YES, man a écrit:

Pour être honnête, je ne connais pas les fonctions throw, try, catch

Et justement c'est un des points les plus importants (mais pas le seul) : dans un langage à exception, si on veut écrire du code correct, la gestion des ressources doit être automatique ou elle se plie immédiatement à la gestion des try/catch etc. Et C++ est un langage à exception. Donc même si tu ne les connais pas, pour que ton code soit correct, il doit y être robuste. Ce que n'apprend pas définitivement pas ce cours.

Pour les autres points, je t'invite à aller visiter les liens qui sont dans le post de blog de @informaticienzero.

-
Edité par Ksass`Peuk 22 mars 2017 à 17:18:37

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

22 mars 2017 à 17:29:43

YES, man a écrit:

Pour être honnête, je ne connais pas les fonctions throw, try, catch (ainsi que unique_ptr et make_unique), peux-tu me dire comment le premier code à rallonge fonctionne ?

Tu as encore beaucoup à apprendre petit scarabé.

Les 2 fonctions font exactement la même chose, de manière propre (sans fuite de memoire):
Allocation dynamique de 2 entier, et retourne la somme de ces derniers.

Les blocs try permettent d'intercepter les exceptions (l'operateur new peut lancer des exceptions), et le bloc catch permet d'y réagir (liberation des ressources allouées dans mon cas).
Le mot clef throw permet d'escalader l'exception en cours.
Comme tu peux le voir, c'est long et lourd à écrire, c'est illisible et nuit fortement à la compréhension.

La 2e fonction utilise les pointeurs intelligents, qui prennent en charge l'allocation / liberation des ressource de manière automatique et sécurisée.

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 17:40:08

Salut,

YES, man a écrit:

J'ai compris des notions que je n'avais pas comprises avec d'autres cours.

J'ai réussi à comprendre exactement la manière de fonctionner des pointeurs (en C)... juste après mon examen de C, alors que j'attendais le train pour rentrer chez moi.

Il se peut que tu aies, effectivement, réussi à comprendre certaines notions avec ce cours. J'irai même jusqu'à dire que c'est très probable, car les explications qu'il donne sont compréhensibles

Mais peux tu décemment estimer avoir compris tous les tenants et les aboutissants des notions que tu dit avoir comprises ?

Il ne suffit malheureusement pas de savoir qu'un pointeur est "une valeur numérique entière représentant l'adresse mémoire à laquelle se trouve un élément d'un type donné", ni même que "on peut demander au système d'exploitation de nous allouer un espace suffisant en mémoire pour représenter cet élément à l'aide du mot clé new pour avoir un code fiable (ce qui devrait être ton premier objectif)

Il faut aussi avoir conscience de "tout ce qui peut tourner mal" et savoir comment y remédier en cas de besoin.

Le cours de nebra s'arrête malheureusement à la première étape, sans prendre la peine de t'expliquer les risques que tu encoures, et encore moins comment y remédieer

Pire encore, certains code sont conceptuellement incorrects. Or, la conception est la pierre angulaire sur laquelle repose tout développement informatique

Même à l'époque où il a été écrit, la dualité entre la "sémantique de valeur" et la "sémantique d'entité" était connue, et on savait exactement comment faire la différence (bien que de manière moins efficace qu'aujourd'hui) : en déclarant (sans les définir) le constructeur de copie et l'opérateur d'affectation dans l'accessibilité privée

Or, nebra persiste à essayer de te vendre le fait que la classe Personnage (dont dérive d'autres classes) doit respecter la forme canonique de Coplien en proposant un constructeur de copie et un opérateur d'affectation valide

J'avais ouvert un fil, et avais eu des réponses pas toujours très cools, et j'ai persisté et signé pour dire merci à Mathieu. On a pu caractériser mon propos d'obtu.... mais à force de chercher le cours parfait, on finit par ne plus rien faire. C'est un grand problème que beaucoup ont. J'ai décidé de ne pas m'arrêter à cela, et j'ai eu raison. Même si j'ai encore beaucoup à apprendre, j'ai déjà beaucoup progressé.

Le problème, mais ca, tu ne pourras t'en rendre compte qu'à la longue, c'est que tu as pris, au travers de ce cours, énormément d'habitudes qu'il te faudra perdre avant de pouvoir commencer à fournir un code fiable.

Et je peux te garantir (pour avoir moi-même du surmonter ce genre de problème, à peu près comme tous les développeur de ma génération, d'ailleurs) que ces mauvaises habitudes seront les plus difficiles à perdre; sans doute parce que "après tout, ca fonctionne très bien comme cela"

Au lieu de chercher la petite bête

Et pourtant, c'est notre "devoir sacré" en tant que professionnels de le faire.

Quand tu développes un truc pour toi (mettons: un jeu) et qu'il plante sans raison apparente, c'est juste frustrant.

  1. parce que tu perds systématiquement ta progression
  2. parce que tu vas passer des heures à t'arracher les cheveux sur le déboggueur
  3. parce que, en corrigeant un problème, tu risques d'en créer d'autres
  4. ...

Quand un professionnel fait une bourde, cela peut avoir des répercussions beaucoup plus graves que le "simple fait" d'obliger l'utilisateur d'une application à la relancer (après avoir perdu deux heures de travail)

Parfois, ce sont simplement quelques millions qui explosent en plein vol, parfois, des personnes sont blessées ou tuées. Parfois, on frôle la troisième guerre mondiale.

Si la vie t'en préserve, tu ne seras sans doute jamais confronté à une situation dans laquelle tu devras te dire que "c'est uniquement ma faute, parce que j'ai été incapable de fournir un code fiable". Et c'est, sincèrement tout le mal que je te souhaites

(Je te rassures, je n'ai jamais été dans une telle situation à cause d'un code que j'ai écrit. Mais j'ai cependant vécu une situation très similaire avant de me rendre compte que je n'étais absolument pas responsable de ce qui s'était passé. Et cette expérience m'a sans doute changé à jamais)

dans les petits trucs qui ne vont pas, il suffit de faire des recherches par soi-même sur youtube, internet quand on ne comprend pas.

Peut être... Mais comment veux tu faire une recherche sur "quelque chose qui ne va pas" si... tu ne sais pas que ce "quelque chose" ne va pas ????

Et si pour certains il y a tant de fautes, et bien qu'à la place de critiquer de cours de Mathieu Nébra, ils envoient un correctif à openclassrooms depuis le temps qu'ils critiquent.

Pour cela, il faudrait

  1. Que Mathieu Nebra veuille mettre son cours à jour
  2. que l'on ait nous même suffisamment de temps à y consacrer
  3. que l'on accepte l'idée que Mathieu Nébra continue à vendre son livre (et se fasse au final du fric "sur notre dos")
  4. Et bien d'autres conditions qui ne me viennent pas forcément en tête pour l'instant

Poiur compléter le cours de Mathieu, il y a des youtubers comme "ProgrammingKnowledge" qui font des superbers vidéos qui peuvent nous aider.

Internet est plein de ressources. De bonnes, comme de moins bonnes. Tout le monde le sait ;)

Mais le problème reste entier:

  • Il est très difficile de perdre les "mauvaises habitudes", surtout lorsque ce sont les premières qu'on a acquises
  • si tu n'as aucune conscience d'un problème, il est très difficile pour toi d'essayer d'y trouver une solution

Je suis vraiment content du cours de Mathieu. Quand on veut acquérir de bonnes bases, ce cours est excellent.

Ummmpffff... C'est toi qui le dit...

Que dirais tu d'en reparler quand tu auras quinze ou vingt ans d'expérience en C++ ???

(car, oui, certains d'entre nous ont autant d'expérience que cela ;) )

Et ce n'est pas parce que on a écrit "using namespace std; " dans un fichier, qu'il y a cata. Ok, c'est vrai, c'est pas optimal dans certains cas, mais on ne devient pas expert du jour au lendemain ....

S'il n'y avait que la directive using namespace std;, ce ne serait pas vraiment le problème.

D'ailleurs, pas mal de points sont "aussi anecdotiques" que cela, et on pourrait, effectivement, dire pour la plupart des points négatifs que "ce n'est pas la cata".

Sauf que ... Tous ces détails mis ensembles produisent une véritable montagne d'informations erronées (où à tout le moins "imprécise"), et que cela en vient à fausser complètement la manière dont tu appréhende le langage; qui en viennent littéralement à saper toutes les bases qui te permettraient de produire un code fiable

Bien sur, tu as tout à fait raison : on ne devient pas expert (surtout en C++) du jour au lendemain. Mais, il faut aussi comprendre que, si les experts décident de juger quelque chose comme "négatif", c'est qu'il y a très certainement une raison

La principale est que, en tant que débutant, tu prendras sans doute beaucoup plus plaisir à produire quelque chose de fiable, que tu puisse utiliser sans risquer que "ca plante" au beau milieu de l'utilisation que de passer des heures à analyser le comportement de ton application en mode "pas à pas".

Oui, bien sur, il se peut que tu trouve le débuggage chouette et sympa... pendant un temps...

Mais, tu peux me croire, tu t'en lasseras vite. Surtout lorsque tu commenceras à y passer plus de temps qu'à n'importe quoi d'autre concernant ton projet.

Le débuggage, c'est sympa... à doses homéopathiques! Car c'est une période pendant laquelle on a plutôt l'impression de reculer alors qu'il y a encore "tant de choses" à faire.

Les conseils que l'on donne n'ont au final qu'un seul but : te donner l'occasion de ne pas te décourager à force de te retrouver face à des problèmes. En tant qu'experts (ou, pour certains, en tant qu'intermédiaire éclairé), il est normal que l'on ait une vision beaucoup plus large des problèmes qu'un débutant.

Tu l'as déjà remarqué, cette vision est partagée par la plupart d'entre nous. Ce n'est certainement pas un hasard ;)

  • Partager sur Facebook
  • Partager sur Twitter
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
22 mars 2017 à 17:45:52

N'inversez pas le timing de l'apprentissage.

- On apprend comment bien coder, efficacement, avec sureté, simplicité, etc...

- APRÈS, on voit comment comprendre du code tout moisi et les astuces que les plus malins ont fait pour palier les "failles" du langage il y a plus de 20ans.

Sinon, on sera pour toujours avec du code tout moisi, jusqu'à la fin des temps.

@Fvirtman, pourquoi fournir une API C++ non opaque à vos librairies ?

Vous leur fournissez une API C opaque et isolé en terme de mémoire, et là, ils vous emmerderont plus.

2/3 fichiers d'en-tête à faire, si les clients sont des bras cassés pas foutu de faire des classes C++ de wrapping, et c'est peinard.

Connaitre le C++, même basiquement et ne pas connaitre " throw, try, catch", c'est un peu comme penser savoir conduire parce qu'on a fini une course sur "Mario Kart", vraiment.

Maintenant, faudra sortir de "Mario Kart" pour prendre de vrais cours de conduite.

>beaucoup de monde a appris énormément de choses grâce à ce cours

BEAUCOUP DE CONNERIES.

> je ne suis qu'à mon premier emploi et un stage de fin d'études

Tu peux faire un peu de DropName, pour qu'on les évite ou qu'on les tonde en tant que consultant "qualité" ?

Moi, je pense à Thales, Sagem/Safran comme ancien clients, mais j'espère qu'ils sont changés depuis le temps (et c'est des grosses boites, ou un service travail comme des cochons et d'autres de manières très carrés).

En résumé, tu n'as pas assez d'expérience pour en tirer des généralités, et moi non plus, même avec 20 ans d'expériences et plusieurs dizaines de boites clientes.

> les gens m'ont regardé avec des yeux ronds et incrédulité

Le fait que cela soit un jeunot joue en ta défaveur. Avec de la bouteille, ils font pas les malins et passe directement à la phase2 : On n'a développé comme des porcs, ça fais 15ans qu'on développe sans le moindre tests unitaires, qu'on a bien niqué le management pour qu'on soit indéboulonnable (enfin c'est ce qu'ils croient, les naïfs) et que c'est tombé plus ou moins en marche il y a 15 ans, quand il y avant 1000 fois moins d'utilisateurs et des milliards de fois moins de données, et que celui qui a produit ce véritable miracle a été automatiquement déifié et promis dans un poste à responsabilité où il ne code plus (le management est lucide, 2 miracles pour la même personne, faut pas croire au père-noël non plus).

P.S.: ouais, avec mon expérience, le développement en France dans les grosses boites, c'est vraiment de la m...., vive les Start-Up.

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
22 mars 2017 à 17:57:14

koala01, merci pour ton long message

merci aussi à Deedolith, je mets un +1

ça me réchauffe le coeur ce soutien sur ce forum

C'est dit avec tellement de bienveillance et de tact. Merci.

En ce qui concerne par exemple, les aspects "fuites de mémoires" que certains ont critiqués, il me semble que le cours de Mathieu a corrigé la chose puisqu'il dit bien que si p est un pointeur, il faut le supprimer un faisant un delete p; suivi d'un p=0    pour éviter le problème de fuite de mémoire.

 Est-ce une bonne pratique ?

-
Edité par pseudo-simple 22 mars 2017 à 18:00:48

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 18:02:45

YES, man a écrit:

Si vous avez des preuves concrètes de choses qui ne vont pas dans son cours, vous pouvez les lister ici

je propose de faire dans ce fil, un catalogue de toutes les choses qui ne vont pas dans le cours.

Ainsi, nous aurons un fil qui concentrera tout ce qui DOIT amélioré, et cela bénéficiera à openclassrooms.com ainsi qu'aux futurs lecteurs d'openclassrooms

Que chacun mette ci-après les passages qui doivent impérativement être corrigés

Comme deja dit, ca deja ete fait.

Et pour que tu ne penses pas que l'on est juste des raleurs qui ne font aucun retour aux auteurs : https://openclassrooms.com/forum/sujet/mise-a-jour-du-cours-c. Et ce n'est pas la première discussion sur le sujet.

Et j'ajouterais que j'ai déjà également parlé avec le community manager a propos de ce problème.

YES, man a écrit:

Et si pour certains il y a tant de fautes, et bien qu'à la place de critiquer de cours de Mathieu Nébra, ils envoient un correctif à openclassrooms depuis le temps qu'ils critiquent.

Notre attitude peut paraître surprenante. Effectivement, pourquoi déconseiller un cours, alors qu'il n'y a pas réellement d'alternative en francais ?

La raison est simple : cela fait des années que l'on se bat avec les erreurs des débutants sur le forum. Toujours les mêmes erreurs qui reviennent. Et on sait que sur le long terme, une mauvaise habitude prise quand on est débutant est très difficile a désapprendre. Et au final, on se retrouve avec des devs C++ qui ne savent pas écrire du code correct.

YES, man a écrit:

Excellent cours de Mathieu Nébra pour le C++

Ce cours explique par exemple très proprement ce qu'est un pointeur.

J'ai déjà fait de belles choses grâce à ce cours.

Ce cours , à quelques petites erreurs, est vraiment en phase avec des codes très performants.

Ne le prends pas mal, mais je vais très direct : ton avis sur la qualité du cours, on s'en moque. Tu n'as pas l'expérience et le recul pour juger du contenu. (Et les 3 phrases que j'ai cité sont un très bon exemple que tu ne sais pas de quoi tu parles).

C'est brutal ce que je dis, mais ce n'est pas méchant. Tu es débutant et ce n'est pas un défaut. Tout le monde a ete débutant. Mais un débutant est incapable de juger de la qualité d'un cours.

Manu310 a écrit:

Toutefois, je suis d'accord avec Yes, man sur un point : beaucoup de monde a appris énormément de choses grâce à ce cours. Et dans le monde de l'industrie et des éditeurs de logiciels, je ne suis qu'à mon premier emploi et un stage de fin d'études dans le domaine, mais à chaque fois, les gens m'ont regardé avec des yeux ronds et incrédulité quand je leur ai parlé de pointeurs intelligents et autres merveilles (pas de sarcasme, je comprends que ces choses là sont vraiment intéressantes et méritent d'être de plus en plus utilisées)... "On n'a jamais utilisé ça ici, et ça fonctionne... Et puis on va pas recoder ce qui est en opération, maintenance, support depuis 15 ans..."

Je ne sais pas de quelle boite tu parles, donc je ne vais pas l'attaquer spécifiquement. Mais dans la majorité des cas, ceux qui répondent "ça fonctionne" n'ont aucune idée qu'ils font de la merde. ("merde" = code difficile a maintenir, pleins de bugs non reproductible, avec des coûts de développements et une dette technique importants).

Ceux qui connaissent leur sujet vont plutot repondre "on utilise du C++ old school parce que l'on a pas le choix, même si cela implique beaucoup de problèmes".

Il y a deux façons de ne pas avoir de problèmes : avoir du code de qualité ou être trop incompétents pour voir les problèmes. Mon expérience (et celle d'autres devs expérimentés) ce que celui qui n'a aucun problème, c'est souvent la seconde situation.

Manu310 a écrit:

Donc je suis d'accord, il faut se mettre à jour, apprendre les nouvelles normes, c'est très enrichissant et il y a toujours de bonnes raisons derrière ces changements de pratique et d'utilisation. Mais comme pour beaucoup de choses, il faut faire le compromis entre la norme et l'usage... Et l'usage, n'est pas aujourd'hui massivement pour le C++11 (encore moins le 14, et le 17, n'en parlons pas) dans l'industrie "traditionnelle", dans le monde de la simulation, de l'aéronautique... pour ce qui m'a été donné de voir par exemple.

Ce point a déjà été expliqué plusieurs fois sur le forum, mais c'est toujours intéressant de revenir dessus.

Premièrement, le problème d'apprendre de mauvaises choses. Je l'ai dit au dessus, cela crée des habitudes et c'est difficiles a perdre. = perte de temps d'apprentissage.

Le second point est une question de pédagogie. Comme d'autres l'ont dit, un code "qui marche" n'est pas forcément un code valide. Apprendre a gérer correctement la mémoire (par exemple) est très complexe et nécessite de comprendre des concepts comme l'ownership ou la duree de vie. 

Le problème est que beaucoup de cours anciens n'apprennent pas correctement a utiliser les pointeurs. Ils donnent la syntaxe, mais sans expliquer ce qui est correct de faire ou non. Tant que l'on copie-colle le code, tout va bien. Dès que l'on écrit son propre code, c'est la catastrophe.

L'utilisation des pointeurs intelligents (par exemple. Mais il y a d'autres choses apportee par le C++ "moderne"), c'est :

1. d'avoir du code safe par défaut. (c'est mieux d'apprendre les concepts derrière les pointeurs sur un code correct que sur un code faux)

2. de définir explicitement l'ownership et la duree de vie. (donc de forcer a apprendre ce que c'est).

L'apprentissage du C++ "moderne" est donc un choix pédagogique, pour faciliter l'apprentissage des concepts fondamentaux du C++. Et quand on connaît ces concepts, on peut faire du C++ old-school correct. 

La majorité (voire "tous" a ma connaissance) des cours old-school sont mauvais non pas parce qu'ils n'utilisent pas du C++11, mais parce qu'ils n'expliquent pas correctement les concepts fondamentaux. (Le concept des pointeurs intelligent existent depuis très très longtemps, et les problématiques aussi - Sutter l'appelle "le problème depuis 30 ans". Pourtant la majorité des cours old-school n'abordent pas cela).

Bref, on risque de continuer encore longtemps de critiquer le cours. Et on a nos raisons pour cela.

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 18:04:02

Quand tu fais delete p; ça ne détruit pas le pointeur, ça désalloue la donnée qu'il pointe (ou pas si c'est le pointeur nul) ou ça fait n'importe quoi dans les autres cas.

Le pointeur, lui, il est détruit à la sortie du bloc où il est déclaré.

Quand au p = 0, ou plutot p = nullptr, il n'évite pas les fuites mémoires, mais c'est une précaution désespérée et un peu infantile contre une double libération, pour les étourdis qui font deux fois delete sur la même adresse.

C'est pas pour chipoter sur du vocabulaire, c'est pour dire que le cours t'a exposé de façon très floue des notions qui nécessitent une grande précision. Et si il te laisse croire, grâce à une rédaction fluide, que tu as tout compris, méfies-toi, c'est dangereux.

Et c'est justement parce que c'est très casse-gueule que les pointeurs intelligents ont été introduits officiellement dans C++, après avoir été utilisés largement à travers des bibliothèques externes, multiples et incompatibles. C'est un vrai besoin.

(Après, y a un vrai souci sur l'enseignement des pointeurs intelligents à des gens qui ne comprennent pas encore la fonction d'un pointeur, vu qu'il faut choisir rationnellement entre plusieurs sortes, qui font des choses pas forcément évidentes à comprendre. Un autre problème ; vouloir enseigner C++  à des gens qui n'ont pas déjà des notions générales de programmation)

.

-
Edité par michelbillaud 22 mars 2017 à 18:11:37

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 18:31:51

YES, man a écrit:

En ce qui concerne par exemple, les aspects "fuites de mémoires" que certains ont critiqués, il me semble que le cours de Mathieu a corrigé la chose puisqu'il dit bien que si p est un pointeur, il faut le supprimer un faisant un delete p; suivi d'un p=0    pour éviter le problème de fuite de mémoire.

 Est-ce une bonne pratique ?

Avec ta question, on peut déduire plusieurs choses :

1. tu ne sais pas utiliser correctement les pointeurs. (Parce que tu ne sais même pas pourquoi ce n'est pas une approche valide de faire cela).

2. Mathieu ne sait pas utiliser correctement les pointeurs. (Et on ne va pas lui reprocher, il n'est pas dev C++. Au pire, c'est au lecteur que l'on peut reprocher de ne pas prendre de recul sur un cours qu'il lit)

3. tu aurais appris les pointeurs intelligents, tu saurais écrire un code valide. Et très probablement pourquoi il est valide.

C'est pourtant un cas d'étude très classique :

auto p = new int;
auto q = new int;
delete p; 
p = nullptr;
delete q; 
q = nullptr;

Pourquoi ce code n'est pas correct ? (J'ai utilisé des syntaxes du C++11, pour bien montrer que ce n'est pas un probleme de C++03 vs C++11, mais bien une problematique liee au pointeurs nus)

Un autre classique :

String EvaluateSalaryAndReturnName( Employee e )
  {
    if( e.Title() == "CEO" || e.Salary() > 100000 )
    {
      cout << e.First() << " " << e.Last()
           << " is overpaid" << endl;
    }
    return e.First() + " " + e.Last();
  }

Dans ce code, combien y a-t-il de chemins nominaux (c'est a dire de points de sortie de cette fonction. Par exemple, elle peut retourner sur le "return", mais egalement si e.First() retourne une exception ou si e.Last() retourne une exception).

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 19:29:10

Gbdivers

peux-tu m'expliquer le problème du code

auto p = new int;
auto q = new int;
delete p;
p = nullptr;
delete q;
q = nullptr;



je voudrais comprendre. Je ne connais pas le problème des pointeurs nus. Si je peux perfectionner mon apprentissage sur cette situation.

Merci pour tes explications

-
Edité par pseudo-simple 22 mars 2017 à 19:30:20

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 19:36:40

L'instruction "new" peut jeter une exception. Dans un tel cas, le flot d'exécution est rompu et les instructions qui suivent ne sont pas exécutées. Si c'est la première, pas fondamentalement de soucis. En revanche, si c'est la seconde (l'allocation pour q), comme les instructions suivantes ne sont pas exécutées, la mémoire de "p" n'est jamais libérée : fuite de mémoire.

En fait on peut simplifier un peu l'exemple en écrivant :

void function_that_can_fail();

int main(){
  auto p = new int;
  function_that_can_fail();
  delete p;
  p = nullptr;
}

Si l'appel à la fonction échoue, le code qui suit n'est pas exécuté : fuite de mémoire.

On pourrait se dire "mais pourquoi diable on aurait des fonctions qui peuvent échouer avec des exceptions ?". Ben il est là tout le problème : il y a PLEIN de raisons :

  • je n'ai pas réussi à allouer ma mémoire,
  • le fichier que j'essaie d'ouvrir n'existe pas, ou il est endommagé et je fais des erreurs quand je le traite,
  • connexion perdue à un serveur,
  • saisie pourrie,
  • etc.

Et la bibliothèque C++ comprends des dizaines de fonctions comme ça : jusqu'à l'affichage !

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

22 mars 2017 à 19:46:02

D'accord, je comprends.

Ksass Peuk, sur ton exemple simplifié, en toute rigueur , que faut-il écrire , avec les pointeurs dits intelligents ou autre, pour avoir un code très propre ?

Comme je suis vraiment sur C++ , je voudrais comprendre ce type de détails.

Merci

-
Edité par pseudo-simple 22 mars 2017 à 19:56:27

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 19:57:55

Ben en toute rigueur sans pointeur :

void function_that_can_fail();
 
int main(){
  int p;
  function_that_can_fail();
}

Mais bon, on simplifie surement un peu trop là. Donc en gardant un élément allouer dans le tas et pas sur la pile :

void function_that_can_fail();
 
int main(){
  auto p = std::make_unique<int>();
  function_that_can_fail();
}

L'élément est bien alloué dans le tas, et nous crée sur la pile une variable de type 'unique_ptr<int>' qui donne comme garantie que quelque soit comment la notre fonction échoue, la mémoire sera bien libérée par le destructeur.

Je simplifie juste un détail sordide des exceptions. L'idée est que ce code nous donne le type garanties qu'on attend d'un programme dans un code à exceptions.

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

22 mars 2017 à 20:09:25

Si je comprends bien ce que dit Gbdivers, cette fonction std::make_unique<int>() apparaît bien même dans les plus anciennes versions de C++ ?

  • Partager sur Facebook
  • Partager sur Twitter
22 mars 2017 à 20:13:21

Alors non, std::make_unique est une fonctionnalité présente depuis C++14, même si en C++11 on pouvait déjà en écrire une équivalente pour créer des éléments de type "unique_ptr" qui eux, était bien présents en C++11. Cependant, comme unique_ptr seul n'est pas suffisant pour avoir toujours toutes les garanties voulues dans tous les cas d'allocations, on s'est aperçu qu'on avait besoin de std::make_unique.

Avant C++11, c'est du côté de boost qu'il faut se tourner, avec les notions de scoped_pointer notamment. Mais la sémantique est un poil différente en raison de l'absence de sémantique de mouvement en C++-03 et avant.

  • Partager sur Facebook
  • Partager sur Twitter

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C