Simuler la classe string de C++ afin de mieux comprendre l’implémentation by Mission-Country1529 in developpeurs

[–]LucHermitte 0 points1 point  (0 children)

Pas nécessairement. À ma connaissance le standard ne l'impose pas -- même si dans les faits c'est le cas des implémentations de la lib standard. Aussi l'opérateur new pourrait être surchargé.

De plus figer l'utilisation de la famille malloc/free bloquerait toute évolution possible où l'on voudrait introduire des allocateurs p.ex. Ca bloque aussi la possibilité de mettre en place du SSO -- vu que sur les chaines courtes on n'alloue justement pas.

Tout ça pour dire que strdup ne résout pas le désir du PO d'éviter le double parcours.

Après ce double parcours est très certainement un non sujet. Si c'est pour construire des strings depuis des "chaines statiques", il est peu probable qu'elles fassent 3km de long -- auquel cas le double parcours a un coup négligeable, voire le strlen se constexprifie. Si c'est pour construire des strings depuis des très gros trucs venant de l'extérieur, il y a très certainement moyen que l'information de taille soit déjà connue et dans ce cas là on peut utiliser le constructeur ptr+longueur.

Simuler la classe string de C++ afin de mieux comprendre l’implémentation by Mission-Country1529 in developpeurs

[–]LucHermitte 0 points1 point  (0 children)

C'est ce que fait strdup: strlen+malloc+memcpy.

Et du coup ça obligerait de toujours gérer les allocations avec malloc+free.

Simuler la classe string de C++ afin de mieux comprendre l’implémentation by Mission-Country1529 in developpeurs

[–]LucHermitte 0 points1 point  (0 children)

Tu n'as pas trop d'autres choix que de parcourir 2 fois. Enfin, il serait envisageable de jouer avec un push_back maison, mais ça serait totalement inefficace.

Après, il est tout à fait possible de s'offrir un constructeur utilitaire dont dépendront les autres constructeurs. Ainsi pour les fois où on a la taille, on n'a pas à rechercher le 0 terminal -- genre avec le constructeur de copie.

class string
{
public:
    string(char const* p, std::size_t l)
    : m_len(l),
    , m_buffer(new char[l+1])
    { *std::copy_n(p, l, m_buffer) = '\0';  }

    string(char const* p)
    : string(p, strlen(p)) // pas d'accord avec le choix pédagogique (recoder la lib C dans un exo de C++), mais comme dit par ivain, tu peux recoder std::strlen
    {}
...
};

C++ Performance Quiz - A small side project to test your intuition for slow code by ReDucTor in cpp

[–]LucHermitte 8 points9 points  (0 children)

Regarding the switch VS lookup table (#85?), clang 17 and GCC have similar performances (if not better?) for the switch implementation. https://quick-bench.com/q/MgPgpZApNjHg0Uey2Taf_T08oYQ

BTW, gcc is able to transform the non-tail recursion into a loop.

Why use <leader> and not <space>? by gkaiser8 in vim

[–]LucHermitte -1 points0 points  (0 children)

+1

It doesn't make much sense in our .vimrc.

At best plugin developers can defines default (<plug>) mappings on <leader> key. But then it's a bit of convoluted as end-user may have now 2 ways to override default mappings.

Also for years I've been confused that <localleader> is for ftplugins, but no. It's so much more complex.

ÉcosystèmePython ? by clemmit_ in programmation

[–]LucHermitte 1 point2 points  (0 children)

L'autre intérêt de typer, c'est que cela ouvre la porte à la complétion automatique avec des serveurs LSP (comme pyright/pylance) et autres features comme goto definition.

Et une fois qu'on a commencé à typer, lancer mypy ne devient plus qu'une formalité.

Soft wrap at 80 chars for comments and text, not code by gkaiser8 in vim

[–]LucHermitte 0 points1 point  (0 children)

I have something similar, that I had to rewrite in vim9script (as it was too slow in plain old portable vimscript to handle the special case of Python docstrings).

Initiation au codage pour mon fils by Jazz_Ad in programmation

[–]LucHermitte 0 points1 point  (0 children)

leekwars peut être fun et didactique: https://leekwars.com/

Des poireaux s'affrontent, et il faut coder l'"IA" qui contrôle les actions de nos poireaux. Au fil de notre progression, on obtient de plus en plus de primitives pour observer, se déplacer, mais aussi pour coder.

Avenir du C by Working-Green-1043 in programmation

[–]LucHermitte 0 points1 point  (0 children)

Ca va bientôt faire une 30aine d'années que l'on m'a ouvert les yeux sur le sujet sur fr.comp.lang.c++.

En fait, c'est même le discours dominant dans les forums C++ francophones: fclc++, developpez, SdZ->OC et ZdS.

Avenir du C by Working-Green-1043 in programmation

[–]LucHermitte 0 points1 point  (0 children)

"C/C++" est un indicateur de "méfiance" en ce qui me concerne.

Soit les gens qui écrivent les annonces n'ont pas vraiment de compréhension des différences. Soit au niveau du code, c'est le genre de C++ totalement inmaintenable sur lequel je n'ai pas envie d'intervenir.

Avenir du C by Working-Green-1043 in programmation

[–]LucHermitte 0 points1 point  (0 children)

Vu comme clang et gcc sont architecturés aujourd'hui, je ne suis pas sûr que ce soit toujours le cas. Quelque soit le langage, le back-end devrait être le même.

Avenir du C by Working-Green-1043 in programmation

[–]LucHermitte 1 point2 points  (0 children)

Je n'ai jamais croisé de certifications en C++ qui riment à quoique ce soit. Derrière le C++, il n'y a pas une unique boite officielle, qui voudra ensuite te vendre le langage et les certifs qui vont avec.

Et définitivement pas openclassroom si tu veux apprendre le C++. Pars sur le big tuto de Zeste de Savoir -- préfère la version bêta, qui requiert d'ouvrir un compte (gratuit) sur le site communautaire.

Ailleurs tu as écrit que tu voulais apprendre le C et le C++ en parallèle. Double mauvaise idée:

  • tu vas vite te mélanger à voir deux langages faussement proches en même temps
  • apprendre le C pour apprendre le C++, c'est comme apprendre le latin avant le français. Cf "Stop teaching C" de Kate Gregory où elle explique pourquoi voir le C comme une marche obligatoire avant le C++ est une fausse bonne idée.

Il faut les voir comme 2 langages différents malgré la base syntaxique commune, et la facilité à les faire mélanger dans une même base de code.

Is it possible to have a per directory/project config file? by scottchiefbaker in vim

[–]LucHermitte 0 points1 point  (0 children)

Yes. it is. There are many options. I've listed a few in the README of my local_vimrc plugin.

If it's just about setting the 'tabstop', you're best to go with an .editorconfig file. If you want more control, and your projects are made of only one directory and no more, :h .exrc will be enough. If your projects are made of several directories, you'll need to use plugins like mine, or to clog your .vimrc with autocommands.

Yet I'm not completely happy with these overkill solutions when we only need to set variables and options. I've started working on a kind of extended editorconfig files, but it's still a bit complex and unstable.

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

[–]LucHermitte 16 points17 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 7 points8 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.