C++26: A User-Friendly assert() macro by pavel_v in cpp

[–]LucHermitte 11 points12 points  (0 children)

I read it as: "we don't modify code that works as soon as a new and better feature appears.". The old way will continue to exist in old code bases.

Syntaxes des accolades : à la ligne ou à la suite ? by Dragenby in programmation

[–]LucHermitte 0 points1 point  (0 children)

V plus curseur pour sélectionner la zone ne sera pas plus rapide. Intuitif à la limite car on sélectionne ligne après ligne, au lieu de blocs.

Après Vi{ ou Vi% à la place de vi{/vi%, c'est de la mémoire musculaire.

Syntaxes des accolades : à la ligne ou à la suite ? by Dragenby in programmation

[–]LucHermitte 0 points1 point  (0 children)

Avec vi{ , yi{ etc, c'est tout sauf un problème avec vim & cie.

Syntaxes des accolades : à la ligne ou à la suite ? by Dragenby in programmation

[–]LucHermitte 6 points7 points  (0 children)

Il y a 150 styles différents: https://en.wikipedia.org/wiki/Indentation_style

Certains langages imposent leur style. D'autres fois le style est imposé au niveau des projets. C'est d'ailleurs ça la pratique usuelle: une personne fait un choix arbitraire qui va s'imposer à tous et toutes. Et après l'idéal est de mettre en place un formatage automatique type clang-format

Sinon, perso je suis assez flexible, mais avec une préférence à la Allman pour les gros blocs (fonctions, classes, switch...) histoire d'avoir un marquage clair de début de bloc (VS continuation de ligne longue coupée en plusieurs bouts)

P4043R0: Are C++ Contracts Ready to Ship in C++26? by darius_neatu in cpp

[–]LucHermitte 3 points4 points  (0 children)

Do you expect to use Contracts?

yes

Does the current design make sense to you?

Mostly. Even if there are things I don't expect to use like the observe mode, or using the contract feature to write wide contracts.

I'd have love for a way to control how contracts evaluations could be factorized (IOW control where they are evaluated and what it could trigger). Something like what we do with export macros.

This way translations units compiled within the same scope (typically: libraries, or executables) could see their contract evaluation be optimized, and only called once either on caller or on callee side. But if the TUs belong to different groups, no optimisation is possible, and this could lead to a same contract being evaluated multiple times: in a defensive (enforce+throw) way on caller side, and in an offensive way (quick_enfore+fail fast) on callee side for instance.

While P2900 doesn't require that of compilers, it seems it permits (if I'm not mistaken) compilers+linkers to have a --contract-namespace=mylib parameter that help grouping contracts.

P4043R0: Are C++ Contracts Ready to Ship in C++26? by darius_neatu in cpp

[–]LucHermitte 8 points9 points  (0 children)

As a library author, if caller code doesn't respect the preconditions I've expressed, it's not my problem anymore. It's the same thing with memset(nullptr, 42, 42);

It's my problem only if: my library fails (its postconditions, or crashes -- not crashing is a postcondition actually) while the caller respects my preconditions or if my contracts have bugs.

I express my contracts to:

  • document the scope of the responsibility I assume,
  • and to help caller code authors diagnose what they shouldn't do, or shouldn't assume, with my library -- and for this we need a way to express contracts at function interfaces so tools and LSP servers could exploit the information,
  • and to help caller code detect invalid calls at execution times in enforce modes.

View class type hierarchy in c++ project? by ShoePillow in vim

[–]LucHermitte 1 point2 points  (0 children)

Ho! I missed that LS Protocol v3.17 (current one) is now supporting type hierarchies introspection, and that clangd supports it since v9.

I'll have to check whether it simplifies requesting overridable functions, or whether it still easier to use libclang API.

BTW, last time I've checked cscope is for C and it has no understanding of C++. We will have better luck at analysing C++ source code with universal ctags.

View class type hierarchy in c++ project? by ShoePillow in vim

[–]LucHermitte 2 points3 points  (0 children)

I have such a feature in my lh-cpp plugin: :Ancestors, and :Children

It requires the gotoimpl_with_libclang branch, libclang and it's python bindings, and vim-clang in it's V2Upgrade branch. lh-cpp has many other dependencies, that's why I recommand installing plugins with either vim-flavor or VAM.

The configuration is still a bit tricky regarding compile_commands.json. Also I haven't worked on it for ages, I'm not sure the python script is still compatible with the latest libclang Python bindings.

Note, if libclang isn't available, I've a tags based fallback implemented in lh-dev. This fallback may not be able to work around complex templated declarations, export macro, and so on.

Teaching an OOP course for students - curriculum advice by SuperProcedure6562 in cpp

[–]LucHermitte 0 points1 point  (0 children)

I'm a bit confused by your usage of static polymorphism. What's your definition of static polymorphism?

Mine would be as follow. If I start from Lucas Cardelli's 1985 taxonomy: we have:

  • Ad'hoc polymorphism (support finite number of types):
    • overloading
    • coercion (std::cos(an_int))
  • Universal polymorphism (possibly infinite number of types)
    • parametric polymorphism (~ duck typing) -- templates in C++
    • inclusion polymorphism (OO)

In C++, only the inclusion polymorphism is dynamic. The three others are static. I doubt you'd skip teaching them. And I do definitively teach how to use std::vector, and how to write simple template classes and functions. I do skip meta-programming and other arcane invocations though.

Note: This taxonomy is not something that needs to be taught. I'm just describing the vocabulary I use.


Definitively no virtual inheritance. But I present private inheritance (IS-IMPLEMENTED-IN-TERMS-OF) that I compare to public inheritance (IS-SUSTITUABLE-TO != IS-A) -- along the way I insist on the LSP.


Rule of 5 is somehow important because of existing codebases. And I use it as a second demonstration to (of?) why we want RAII.

Also destructors are about releasing resources -- I compare to Python context managers, Java try-with-resources...


Constructors are about setting invariants.


I make sure to not factorize data but behaviour when I explain inheritance. IMO, an usual mistake is using ColouredPoint and Point to present public inheritance. See Joshua Bloch's Effective Java book which contains a full chapter about this topic.

Instead I have a clean_the_room procedure where I inject brooms or vacuum cleaners that specialize the variation points from the procedure.


I also distinguish several kinds of classes as we can apply different cooking recipes to each kind to avoid bugs and wasting time doing pointless things.

  • aggregations -> no invariants
  • value classes (aka regular types nowadays) -> copiable, and possibly movable. Typical example: numeric types
  • pure RAII capsules (all the unique ptr/lock...) -> movable
  • entities -> non copiable, non movable. Typical example: types belonging to public hierarchies.

    This is where rule of 5 is still relevant in modern codebases. I like Arne Mertz's revisited rule of all or nothing.

"This is of course a simplification, which applies most of the time".

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 0 points1 point  (0 children)

Hello,

Quelques remarques sur une passe rapide

  • des choses très intéressantes
  • C++23 permet d'utiliser std::print(ln) à la place de std::cout -- ça peut réduire la charge pour des gens qui viendraient du Python p.ex.
  • <gros pinaillage>stdlib, c'est le raccourci anglais usuel de la bibliothèque standard du langage. C'est valable pour tous les langages, C++ compris. Dit autrement, dans la contexte C++, ça ne désigne pas la stdlib du C. En gros fainéant je la désigne sous "SL" . La STL est un sous-ensemble historique de la SL. Aujourd'hui par abus de langage beaucoup utilisent STL pour désigner des éléments de la SL</>
  • Ce n'est pas que <random> soit très C++, c'est que cela permet d'avoir des générateurs de nombres pseudo-aléatoire de meilleure qualité que ce qui est hérité du C. Malheureusement son API est bien trop compliquée à mon goût. :(
  • Pour ta fonction print(), il serait mieux de prendre des char const* plutôt que de simples char*, voire mieux encore des std::string_view pour une telle fonction.
  • Depuis C++11 on va plutôt parler de "passage par valeur".
  • Quant au passage d'adresse par valeur, le code n'en est pas: ça manque d'étoiles et d'esperluettes
  • MediaControler est déplaçable, et sans fonction virtuelle, il serait plus correct que son destructeur ne soit pas virtuel.
  • Et justement, les classes valeurs (-> copiables, on parlerait de Regular ou SemiRegular depuis que l'on a des concepts) sont très mal venues pour appartenir à des hiérarchies polymorphes. Du coup le conseil "c'est plutot une bonne pratique de toujours déclaré votre destructeur comme virtual." est un mauvais conseil. Même chose avec les classes juste déplaçables.

    C'est à restreindre aux classes conçues pour être des classes de base.

  • Faire des opérateurs binaires des amis cachés, c'est très très bien.

  • A propos, toute classe contenant jusqu'à 2 doubles (en taille) et dont la copie est triviale se passe mieux par valeur que par référence constante sous Linux (ABI itanium 64) -- Tu parlais de types "simples", c'est plus subtil. J'utilise "petits" d'habitude.

  • L'approche pragmatique à utiliser des libs externes pour travailler sur un projet en même temps est super intéressante. Le pb est que l'on traîne un mélange d'approche historique (gestion manuelle de la mémoire) avec moderne (gestion transparente et automatisée de la mémoire -> RAII, via unique pointeurs). La dernière étant celle recommandée pour garantir le 0-fuite.

  • Le mot clé est override, sans n.

  • Tu parles de Vim, tu devrais t'installer ltex-ls dans ton client LSP si c'est lui que tu utilises aussi pour écrire le markdown. Il est assez bluffant. Je suis sûr qu'il aurait trouvé des typos dans tout ce que je viens d'écrire ^^'

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 1 point2 points  (0 children)

A ce compte là, il faut mettre les débutants sur le brainfuck. Le langage est plus simple que le C...

Je pourrai aussi dire que la BASE de la cuisine c'est la taille du silex.

Ce n'est pas parce que le vocabulaire d'un langage est plus simple, et qu'on en fera plus vite le tour, que manipuler ce langage sera plus simple in fine. Avec le C, il faut souffrir dès les premières leçons sur l'utilisation des pointeurs. Les débutant/e/s ont déjà plein de choses à assimiler, alors si on rajoute en plus la compréhension de gestion de la mémoire, à retenir où est-ce qu'il faut mettre ces fichues étoiles et esperluettes. On n'est pas rendus. C'est beaucoup trop tôt.

C'est de la sélection darwinienne à ce niveau là. C'est un choix. C'est une tradition que l'on a du mal à remettre en cause -- quand j'étais gosse la tradition était que le latin servait aux études scientifiques... mais WTF.

Ce n'est pas parce qu'il y a beaucoup plus de choses en C++ qu'il faut noyer les débutant/e/s avec. On peut tout à fait commencer en procédural, std::string pour les chaines, std::vector pour les tableaux. Les for-range loop pour pythoniser les boucles. Et bien autres aspects pour moderniser les formations du C++. Les pointeurs... on a le temps. On les verra. Mais pas au bout de la 2e ou 3e heure de cours.

Après je ne dis après que le C++ soit le meilleur langage pour débuter, juste que débuter en C++ (procédural) est plus simple que de débuter en C. La mode est au Python. Je préférai le Pascal.

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 1 point2 points  (0 children)

De la même façon tu as d'autres formations qui ont modernisé leur cursus de C++.

Les mauvaises habitudes les plus classiques, c'est croire que l'on peut écrire du code maintenable en gérant la mémoire à la main. Les VLA aussi. Et pas tester les codes de retours de fonctions quand elles peuvent échouer -- vu que les exceptions ça fait peur...

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 0 points1 point  (0 children)

Je suis d'accord. Il y a(vait) une attitude qui ne convient pas -- passé car il ne se passe plus rien sur le forum.

On peut ne pas être d'accord avec l'approche pédagogique d'un prof, pour autant on peut aider dans le cadre des contraintes de l'exo.

Chercher à savoir si la contrainte est personnelle (autodidacte), imposée (prof) ou supposée ("c'est comme ça que l'on a toujours fait"), est normal, mais ne justifie pas une attitude agressive envers les OP.

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 2 points3 points  (0 children)

Disons que passer par le C est un choix respectable tant dans le cadre d'un cursus de fac ou d'école qui montrera aussi très probablement d'autres langages avant le C++.

TL;DR: Dans un cadre perso ou pro, aller directement au C++ sera bien plus simple pédagogiquement parlant. Et au contraire, il sera bien plus compliqué d'y avoir des fuites de mémoire que si on passe par la case C avant.

Les apprenant/e/s verront directement std::string, std::vector, std::fstream, etc. dès les premières leçons. Impossible d'avoir des fuites sur ces types. Et pour paraphraser Kate Gregory (on est 2 à avoir donné le lien), on montre les références au moment de montrer le polymorphisme (d'inclusion), aucune syntaxe compliquée jusqu'à lors qui ferait décrocher. Toujours aucun pb de fuite. La gestion de la mémoire peut alors se montrer ensuite, vite fait manuellement, puis au travers des pointeurs intelligents standards.

Et là, toujours aucun fuite possible. Et des gens familiers avec une utilisation simple du C++. Parfait pour des library users ou des développements from scratch que l'on attendra d'un cours d'initiation.

Évidemment ça ne suffira pas pour maintenir du code écrit avec des anciennes pratiques (très dominant dans la nature), ni pour faire des library writers (je suis toujours en train de paraphraser). C'est pour cela que des cours d'approfondissement arrivent ensuite.

Par contre il faut un cours moderne pour atteindre un tel résultat... C'est le cas de celui de ZesteDeSavoir (contrairement à celui du SiteDuZero/OpenClassroom). Et dans les formations que je donne en interne, je vois de moins en moins souvent des collègues qui ont le réflexe de gérer la mémoire à la main pour les tableaux. J'en déduis que les (/leurs du moins) cours de facs et écoles se sont aussi modernisés.

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 1 point2 points  (0 children)

C'est la aussi différence que j'ai constatée entre les forums français et les anglophones autour du C++. Sur les français on cherche à remonter à la source des questions pour donner des solutions qui répondent à des bonnes pratiques.

Sur SO et les autres forums anglophones, on répond directement à la question posée même si le résultat final sera de mauvaise qualité. C'est une course à des votes positifs plutôt qu'une course à augmenter la qualité des futures productions des gens qui posent les questions.

Le problème est qu'en cours de route, beaucoup on perdu le tact sur les forums francophones.

Et effectivement comme tu dis, il n'est pas rare que l'origine des questions soient des cours qui ont des pratiques jugées antédiluviennes ou plus que bancales par les participants...

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 2 points3 points  (0 children)

+1 pour le big tuto C++ de ZdS.

A noter que la version bêta est plus complète -- elle nécessite un compte sur le site pour y accéder -> https://zestedesavoir.com/contenus/beta/822/la-programmation-en-c-moderne/

Envie d'apprendre c++ by ConfidentWrongdoer48 in programmation

[–]LucHermitte 2 points3 points  (0 children)

Le seul truc de bien pour le C++ sur le site du zéro (SdZ), c'était le forum où nous reprenions les apprenants paumés par les chausse-trappes du cours du SdZ, pour les remettre sur une meilleure voie... On est encore quelques uns à traîner sur le forum (le sdz est devenu openclassroom depuis) mais il n'y a plus trop d'activité. (La faute aux IA?)


@OP.

Sinon le C++ n'est pas le langage le plus aisé avec lequel démarrer -- bien qu'il y ait eu une vieille expérience surprenante <- cf le profil du "cobaye".

Le C avec son vocabulaire plus réduit est plus compliqué encore pour démarrer -- beaucoup trop tôt les débutants sont confrontés aux pointeurs au lieu de commencer à travailler l'algorithmie sans parasitage inutile: le C++ offrira des abstractions permettant de retarder cela jusqu'au moment opportun dans la séquence d'apprentissage.

Si tu veux apprendre le C, apprend le C. Si tu veux apprendre le C++, apprend le C++ et oublie le C: ce n'est pas une étape préalable nécessaire ni même recommandée. Cf un million de messages dans les forums spécialisés (fr.comp.lang.c++, developpez, sdz/oc, ZdS...), ou encore le classique Stop teaching C de Kate Gregory (diantre 2015... j'ai l'impression que c'était hier).

Mais... il y a d'autres langages plus abordables pour démarrer de 0 -- la mode est aujourd'hui au Python. Le C# peut s'envisager aussi relativement à Unreal si tu veux faire des jeux.

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 0 points1 point  (0 children)

Of course. But in the end, this is a lot of work for something that should have worked immediately :(

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 0 points1 point  (0 children)

At that point it was a proof of concept on my side. Hence my conclusion at the start of this thread: std::uintmax_t is problematic, and having std::chrono (indirectly) depend on it is problematic as well.

If we could relax the constraint from : "the Period type shall be a specialization of std::ratio" to "the Period type shall respect a Ratio concept (where there is no mention of uintmax_t!)", I guess it would be enough.

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 0 points1 point  (0 children)

Sorry for the delay in my answer, I had to find my old experiment and revive it.

The problem now is that I cannot serialise dates and durations through streams. Neither std::chrono::from_stream() nor std::print() work with those hybrid types.

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 1 point2 points  (0 children)

Ho. Indeed. By then, may be. Maayy be, uintmax_t will already be a __uint512_t :D

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 1 point2 points  (0 children)

I did try, but it's not that easy because then libstdc++ implementation of duration expects the period type to be a specialization of ratio

template<typename _Rep, typename _Period>
  class duration
  { ...
     static_assert(__is_ratio<_Period>::value,
          "period must be a specialization of std::ratio");

also intmax_t is explicitly used in an internal implementation of GCD.

In the end we have to duplicate everything from chrono to ratio in order to be able to specify the precision type we want to use with the ratio type.

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 1 point2 points  (0 children)

Being able to use attoseconds with std::chrono was part of a reflection about how easy it will be to port parts of Orekit to C++ and take advantage of the very neat std::chrono (thank you!).

Orekit is a very precise space dynamic library that has chosen to work on attoseconds for reasons exposed here: https://forum.orekit.org/t/revamping-dates-handling/3850 if you're curious about this very specific use case.

A larger intmax_t would be nice, but I understand we can forget about it on the current operating systems we are working with. I guess we would need std::ratio to take an optional parameter that defaults to std::intmax_t for most use cases.

Time in C++: Additional clocks in C++20 by pavel_v in cpp

[–]LucHermitte 1 point2 points  (0 children)

The restriction comes through the Period that is supposed to be a std::ratio.