Le C++ moderne « ne nous sauvera pas », car il est moins sécurisé que les nouveaux langages,
Selon Alex Gaynor

Le , par Bill Fassinou

134PARTAGES

29  2 
Le monde informatique et plus particulièrement le domaine de la programmation n’a pas l’habitude de délaisser les technologies qu’il a vues naître notamment les langages de programmation. Le Cobol a traversé pas mal de décennies déjà et a fêté, il y a peu, ses soixante ans, le C est toujours en activité et répond présent lorsqu’il s’agit de développer ou de construire des systèmes d’exploitation et, même si le Fortran et le Pascal ou encore le langage Haskell ne couvrent plus une grande partie de la communauté, ils existent toujours et sont utilisés par quelques développeurs. Pourtant les nouveaux langages sont là. Ces derniers que plusieurs appellent les jeunes langages, promettent la robustesse, moins ou l’absence de vulnérabilités, la sécurité par défaut ainsi que de la rapidité.

Ces nouveaux langages sont-ils plus utiles que les anciens ? Si oui, faudrait-il que les développeurs pensent à faire le saut vers ces langages ? Selon Alex Gaynor, un ingénieur, qui a souligné quelques défauts du C et du C++ dans un billet de blog, il est plus que temps pour que les développeurs pensent à migrer vers d’autres langages plus modernes comme Rust, le langage développé par Mozilla Research ou Swift, car, dit-il, ces langages sont sécurisés par défaut. Cependant, dans la plupart du temps, la conception de ces nouveaux langages de programmation a été fortement influencée par l'expérience acquise avec les langages précédents, qu’il s’agisse de la syntaxe ou encore d’autre chose. Le langage Rust par exemple est lui fortement influencé par le C et le C++.

Même si c’est le cas, Alex considère néanmoins ces langages plus sécurisés que leurs prédécesseurs, le C vieux d’un peu moins de 50 ans et le C++ apparu courant 1983. D’après les tests présentés et les explications d’Alex Gaynor, le C et C++ induisent un nombre très considérable de failles de sécurité au sein des applications dont ils sont l’outil de conception. « Ma conclusion basée sur l'examen des preuves de nombreux projets logiciels de grande envergure utilisant C et C ++, est qu'il est nécessaire de migrer notre secteur vers des langages sécurisés par défaut tels que Rust et Swift », propose-t-il comme solution aux nombreux problèmes qu’il a soulignés.

Il estime que, même si le C++, dans sa forme moderne, a apporté quelques fonctionnalités remarquables comme les pointeurs intelligents pour résoudre un certain nombre de ces problèmes, il n’en demeure pas moins qu’il « ne nous sauvera pas ». Alex assure que tous les soucis de vulnérabilité que présente le C++ ne peuvent pas être résolus par les idiomes ou les syntaxes modernes qui lui sont apportées. Ainsi, dans son billet, il met en évidence un certain nombre d'idiomes C++ complètement modernes qui génèrent des vulnérabilités. Il a noté des vulnérabilités permettant de masquer la référence use-after-free et une de ses variantes qui consiste à utiliser le support lambda de C++ pour masquer également une référence, ainsi que d’autres vulnérabilités au sein de la bibliothèque standard du C++, la STL, notamment au niveau des structures de données.


Alex Gaynor

Il affirme que comme toutes les structures de données STL, la méthode operator[] de span n'effectue aucune vérification des limites. Ceci, dit-il, est regrettable, car l’opérateur[] est la façon la plus ergonomique et la plus simple d’utiliser les structures de données. Il continue en disant que std::vector et std::array peuvent théoriquement au moins être utilisés en toute sécurité, car ils offrent une méthode at() vérifiée (« en pratique, je ne l'ai jamais vue faire, mais vous pouvez imaginer un projet utilisant un outil d'analyse statique. qui a simplement interdit les appels à std::vector<T>::operator[] »). span n'offre pas de méthode at(), ni aucune autre méthode qui effectue une recherche contrôlée par les bornes, a-t-il déclaré.

Pour finir, Alex affirme que les idiomes modernes en C++ introduisent de nombreux changements susceptibles d’améliorer sa sécurité. Les pointeurs intelligents expriment mieux les durées de vie attendues, std::span vous permet d’avoir toujours une longueur correcte, std::variant fournit une abstraction plus sûre pour les unions. Cependant, continue-t-il, le C ++ moderne introduit également d'incroyables nouvelles sources de vulnérabilités en plus de ceux qu’il a hérités du C. À ce propos, rappelons que le mois passé, WhiteSource a présenté un index selon lequel le langage C serait le langage de programmation le plus vulnérable aux failles de sécurité les plus connues dans la communauté open source.

WhiteSource a indiqué qu’en dix ans, C a montré un nombre de vulnérabilités très important. Il a été donc placé en tête de la liste des langages les plus vulnérables avec une faiblesse reconnue à 47 % de toutes les vulnérabilités signalées. Pour former le trio des langages présentant le nombre de vulnérabilités le plus élevé, le PHP et le Java suivent respectivement avec 17 % et 12 % des vulnérabilités connues. Le JavaScript vient en quatrième place avec 11 %, le Python et le C++ restent en cinquième place avec 6 % chacun et le Ruby ferme le podium avec un nombre de vulnérabilités open source connu de 5 %. Il a été présenté comme le langage le moins vulnérable parmi les sept langages de l’étude.

Cela dit, Alex a-t-il raison d’affirmer que les langages Rust ou Swift sont plus sécurisés que le C et le C++ ? Non pour certains adeptes de ces deux langages de programmation. Ils ne sont pas du tout d’accord avec l’index de WhiteSource et encore moins avec ce qu’affirme Alex. Pour eux, le problème n'est pas les langages C/C ++ eux-mêmes, mais que ce sont les développeurs qui implémentent des systèmes sans trop penser à bien les sécuriser comme cela se doit. D’autres expliquent que le C++ se retrouve être un langage de programmation très sécurisé lorsqu’on ne fait pas usage des fonctionnalités qu’il a héritées du C. Le C serait-il le langage en tort ?

Dans le même temps, certaines donnent raison à Alex Gaynor. « Un problème important que j'ai eu avec C++ est que, même si votre base de code est du pur C++ 17, la bibliothèque standard est un monstre de Frankenstein hérité du C++ moderne qui nécessite de nombreux compromis. Une bibliothèque standard qui présente les capacités du C++ 17 de manière propre devrait supprimer une bonne partie de la compatibilité ascendante dans les environnements C++ modernes », affirme l’un d’entre eux. Pour éviter ce problème, d’autres préfèrent utiliser leurs propres bibliothèques.

« C++ étant mon langage principal, pour travailler sur mes bases de code, j'ai abandonné la bibliothèque standard et mis en œuvre mon propre remplacement. Je suis sûr que ce n'est pas du tout pratique, mais cela me permet de faire évoluer la bibliothèque avec de nouvelles révisions du standard C++ sans être absolument fixé sur la compatibilité ascendante », a ajouté un autre. De son côté, Alex a continué d’insister sur le fait qu'il serait plus judicieux d’utiliser des langages sécurisés par défaut. « Mon expérience professionnelle avec le C++ relativement moderne et de l’audit du code Rust (y compris du code Rust qui fait un usage important de l’insécurité) est que la sécurité du C++ moderne n’est tout simplement pas la même que celle des langages sûrs comme Rust et Swift », a-t-il déclaré.

Source : Billet de blog

Et vous ?

Êtes-vous du même avis qu'Alex Gaynor ? Pourquoi ?
Avez-vous aussi été confronté à ces problèmes avec votre code ou dans du code legacy ?
Faut-il abandonner le C et le C++ pour d'autres langages comme Rust ou Swift comme il le propose ? Pourquoi, selon vous ?

Voir aussi

Le langage de programmation Cobol fête ses 60 ans, peut-il encore tenir longtemps face à la concurrence des nouveaux langages ?

Quel langage de programmation comporte le plus de vulnérabilités en matière de sécurité ? Une étude de WhiteSource

Quelle est la plateforme de développement ou le langage le plus exposé aux vulnérabilités ? Une étude de Veracode donne des éléments de réponse

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de lsbkf
Membre habitué https://www.developpez.com
Le 24/04/2019 à 2:35
C'est qui lui ? Oh un ingénieur. Si c'est un ingénieur, c'est qu'il a forcément raison !!
Blague à part, c'est écrit où que C++ recherchait la sécurité ? operator[] ne vérifie pas les dépassements, pauvre petit chou. Et alors, si t'en veux pas tu l'utilises pas, mais après c'est qui qui doit se plaindre de ces applications qui bouffent tout le CPU comme s'ils étaient seuls à s'exécuter.
10  1 
Avatar de jo_link_noir
Membre émérite https://www.developpez.com
Le 24/04/2019 à 4:03
Citation Envoyé par darklinux Voir le message
Bref , un langage sécurisé " par nature " , cela n existe pas
Peut-être, mais certains se le veulent plus que d'autres. Le coup des références invalident est très facile à faire en C++, et à contrario, difficile à diagnostiquer. Un exemple tout bête:

Code : Sélectionner tout
1
2
3
char const* cstr = to_string(x).c_str();
foo(cstr); // oups to_string retourne un temporaire et cstr pointeur sur un pointeur désalloué.
Ok, c_str() sert principalement pour les vieux code ou les bibliothèques C, mais il existe des problèmes similaires avec une lambda qui capture une référence pour lesquels le compilateur ne dira absolument rien. Ce n'est pas pour rien qu'il y a une option -Wlifetime en cours de développement dans clang, même si cela ne pourra pas tout détecter.

Alors que les langages comme Rust intègre au cœur même du langage une vérification sur le partage et le propriétaire d'une valeur. Le code du genre au-dessus ne compilera simplement pas. Les nouveaux langages essayent aussi d'avoir comportement plus sûr par défaut comme l'immutabilité, pas de conversion implicite, etc et une syntaxe qui laisse moins de place aux erreurs.

Donc, un langage entièrement sécurisé n'existe probablement pas, mais les langages plus sûrs, si.

EDIT: Pour libc++ il y a _LIBCPP_DEBUG=1, mais j'ai déjà eu des bugs avec :/. Pour libstdc++, il y _GLIBCXX_DEBUG, plus violent que _GLIBCXX_ASSERTIONS, mais qui change l'abi.
9  0 
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 24/04/2019 à 3:40
Citation Envoyé par lsbkf Voir le message
operator[] ne vérifie pas les dépassements
Ce qui est voulu mais en plus non toujours vrai.
Sur vs2017 l'implémentation est la suivante
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
_NODISCARD _Ty& operator[](const size_type _Pos)
		{	// subscript mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (size() <= _Pos)
			{	// report error
			_DEBUG_ERROR("vector subscript out of range");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 #endif /* _ITERATOR_DEBUG_LEVEL */

		return (this->_Myfirst()[_Pos]);
		}
Donc oui il y a vérification en debug, et aucune en release, comme tout bon code devrait logiquement faire.
8  0 
Avatar de Pyramidev
Expert confirmé https://www.developpez.com
Le 26/04/2019 à 14:32
Citation Envoyé par Andarus Voir le message
ça marche comment sans ajouter aucune instruction à l’exécution j'ai du mal à comprendre?
Par exemple, Rust pousse l'idée du RAII jusqu'au bout. En C++, si on lit une variable non initialisée, on a un comportement indéterminé. On peut aussi avoir un comportement indéterminé si on lit un objet dans un moved-from state (quoique ça dépend du type). En Rust, par contre, ce genre d'erreur entraîne une erreur de compilation, car les durées de vies sont plus strictes.

Un autre exemple en C++ est celui où on appelle std::string::c_str() et stocke le résultat dans une variable (appelons-là ptr). Plus tard, si on modifie la chaîne (par exemple avec std::string::append), l'implémentation peut avoir besoin de déplacer la chaîne ailleurs en mémoire. ptr devient alors un dandling pointer et représente une source de danger.
En Rust, par contre, pour toute variable muable, si on garde une référence dessus capable de modifier cette variable, alors cette référence doit être unique, tant qu'elle est accessible. Donc on ne peut pas appeler l'équivalent de std::string::append tant que la chaîne est déjà accessible ailleurs (via ptr). Pour que ça compile, il faut d'abord que ptr ne soit plus accessible. On peut alors appeler l'équivalent de std::string::append. Ce genre de contrôle se fait aussi à la compilation.

Il y a encore d'autres contrôles. Pour plus de détails, je conseille les chapitres suivants de The Rust Programming Language :
8  0 
Avatar de koala01
Expert éminent sénior https://www.developpez.com
Le 29/04/2019 à 10:06
Citation Envoyé par yrazet Voir le message
Hello, je me suis inscrit juste pour répondre à ce message.
Bienvenue sur le forum

A titre d'expérience, j'utilise un allocateur de debuggage en C++. Chaque allocation mémoire est tracée et si il y a oubli d'un delete, mon programme me le dit avec le numéro de ligne et l'allocation qui à été oubliée. Sur un assez gros programme, j'ai fais deux erreurs d'allocation. Pas bien réveillé, en déplaçant les allocations à un autre endroit et en oubliant de déplacer les deletes avec. L'allocateur m'a rappelé à l'ordre en me disant vous avez oublié de libérer deux blocs a tel endroit.

Sous VC++, l'allocateur de debuggage, vous mettez ça dans votre stdafx.h puis vous remplacez vos new par DBG_NEW.
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
#if _DEBUG 
	#define _CRTDBG_MAP_ALLOC
	#include <crtdbg.h>

        #ifdef _DEBUG
              #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
        #else
              #define DBG_NEW new
#endif
On l'a tous fait au moins une fois

Mais, pour être honnête, il y a "à boire et à manger" dans la pratique...

Il y a, en effet, d'énormes avantages à utiliser un tel système (ne serait-ce que le fait que l'on puisse suivre les allocations de mémoire), mais il y a d'énormes inconvénients, qui découlent tous d'un fait tout bête : tu utilises une fonction qui t'est propre (DBG_NEW), ce qui implique:
  1. que les allocations "tièrces" (comprends : exécutée en dehors de ton projet) ne sont pas prises en compte
  2. qu'il est impossible, même si ton projet est correctement "saucissonné", de ne récupérer qu'une seule classe, une seule paire de fichiers d'en-tête (*.h / *.hpp) et d'implémentation (*.cpp) pour "autre chose" sans soit avoir besoin d'y ajouter <crtdb.h> (quid si un autre système similaire existe déjà dans l'autre projet ) ou sans avoir besoin d'en modifier le code pour pouvoir l'utiliser

Ce n'est -- bien sur -- absolument pas catastrophique, mais, disons que cela présente malgré tout un frein de taille à la réutilisation potentielle de ton code

Sinon, j'utilise pas les shared_ptr pour diverses raisons, si je me trompe pas, par exemple, il aura fallu attendre la v17 pour que shared ptr prenne en charge les tableaux.
Tu as raison, mais le fait est que, de toutes façons, le couple std::shared_ptr et std::weak_ptr ne devrait pas être ton choix "par défaut".

"Par défaut" (comprends: si tu n'as aucune raison de faire autrement), le meilleur choix de pointeur intelligent est d'utiilser std::unique_ptr, ne serait-ce que pour ne pas avoir à payer le coût d'un comptage de référence qui s'avère bien souvent inutile

En outre, "la logique" voudrait que l'on n'utilise l'allocation dynamique que pour les classes dites "à sémantique d'entité", étant donné que l'on dispose déjà de deux classes (std::vector et std::array) pour représenter la notion de "tableaux", et que ces deux classes fournissent (lorsqu'elles sont correctement utilisées, cela va de soi) toutes les garanties nécessaires.

Mais je les utilise pas pour d'autres raisons, parce que quand on fait une allocation on doit savoir ou et quand on en a plus besoin, ce qui élimine de facto le besoin d'un shared_ptr. Si il y a besoin c'est un peu inquiétant.
Tu as raison sur ce point de vue.

Malheureusement, les choses ne sont pas aussi simples que cela, pour une simple et bonne raison : C++ est un langage à exception.

Un code aussi simple
Code : Sélectionner tout
std::cout<<"hello world";
pouvant parfaitemet lancer une exception, il est très difficile de prévoir tous les chemins d'exécution qui pourraient nécessiter la libération d'une ressource allouée de manière dynamique.

C'est la raison de la mise en place de ce que l'on appelle des "capsules RAII" (dans la catégorie desquelles on trouve std::unique_ptr et std::shared_ptr): ce sont des données qui se trouvent -- a priori -- sur la pile, qui sont donc automatiquement détruite lorsque l'on sort de la portée dans laquelle elles ont déclarées (comme n'importe quelle donnée sur la pile), et provoquent donc automatiquement la libération de la ressource allouée de manière dynamique.
A coté de ça, j'utilise pas/peu non plus les notions "moderne" du C++. Je me limite aux containers, aux fonction de tri, peut être un ou deux autre trucs que j'ai oublié aussi.
A l'exception des pointeurs intelligents, dont on vient de parler, c'est une approche que l'on peut comprendre, mais qu'on ne va sans doute pas plébiciter

La plupart des fonctionnalités apportées par C++11 et ultérieures permettent en effet de rendre le code plus sur (là où il y avait un manque flagrant de sécurité) et au compilateur de générer du code plus rapide.

La déclaration des fonctions membre comme étant delete, par exemple, nous permet d'écrire un code proche de
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
class MyEntity{
public:
    /* une classe ayant sémantique d'entité ne peut être ni copiée ni assignée */
    MyEntity(MyEntity const &) = delete;
    MyEntity& operator=(MyEnity const &) = delete;
    /* le destructeur d'une classe ayant sémantique d'entité sera soit public et virtuel, soit 
     * protected et non virtuel 
     */
    virtual ~MyEntity() /* = default */;
};
là où il aurait fallu attendre l'édition de liens pour se rendre compte d'un éventuel problème avec un code proche de
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Avant C++11, on aurait travaillé de la sorte */
class MyEntity{
public:
    /* le destructeur d'une classe ayant sémantique d'entité sera soit public et virtuel, soit 
     * protected et non virtuel 
     */
    virtual ~MyEntity() 
private:
    /* on aurait déclaré le constructeur de copie et l'opérateur d'affectation
     * dans l'accessibilité privée, et ON NE LES AURAIT SURTOUT PAS
     * IMPLEMENTES
     */
    MyEntity(MyEntity const &);
    MyEntity & operator=(MyEntity const &);
}
Pire encore, si, par distraction, le développeur de MyEntity venait à fournir une implémentation du constructeur de copie et / ou de l'opérateur d'affectation, cela aurait pu occasionner quelques bugs très spécifiques

De même, les mots clé override et final obligent le compilateur à s'assurer que les fonctions pour lesquelles ont redéfini le comportement existent bel et bien dans la classe de base, et qu'elles sont bel et bien virtuelles.

Il suffit de "si peu" (une étoile ou une esperluette en plus ou en moins pour le type de retour ou pour la déclaration d'un paramètre, par exemple) pour que l'on assiste à une surcharge de la fonction (qui n'est pas virtuelle) au lieu d'assister à une redéfinition de la fonction virtuelle que ce serait vraiment très dommage de ne pas forcer le compilateur à faire cette vérification

Mais même les lambda que je trouvais sympa à la base j'évite de les utiliser.
Là encore, c'est une approche que l'on peut comprendre...

Après tout, nous nous en sommes passé pendant 13 ans, en créant au besoin un foncteur spécifique à l'intérieur d'une fonction hein

Cependant, le système avait malgré tout ses limites... Et ce sont ces limites qui ont été repoussées grâce aux expressions lambda

Il est -- encore une fois -- dommage que tu restes "bloqué" par des limites qui ont pu être abolies par la nouvelle norme

Je crois on pourrait appeler mon style de programmation du C avec des classes plutôt que C++ ou C++ moderne.
Ca, c'est sans doute le plus gros problème!!!

Le C with classes n'a été développé à la base que pour servir de "fondation" au C++, parce qu'il fallait bien avoir "quelque chose" qui soit susceptible d'être compris par un compilateur C pour pouvoir générer le compilateur C++.

Mais, dés le départ, C et C++ ont été des langages différents, même si les premiers utilisateurs de C++ n'en avaient pas forcément conscience. Et, même si C++ a tout fait (du moins, au début) pour assurer une "certaine compatibilité" avec le C, la différence entre les deux langages n'a pu que s'amplifier avec le temps
Je préfère faire attention à ce que mes programmes restent lisibles et tout de suite compréhensible 6 mois plus tard même pour un programmeur Java.
Et tu as encore une fois bien raison!

Seulement, la manière dont tu t'y prend n'est peut-être pas la bonne
Ce qui n'est plus possible avec du C++ moderne, selon moi.

C'est là que tu te trompe

Les expression lambda (par exemple) sont apparues en 2006 en java. Tu ne dois donc pas avoir peur qu'un développeur java ne comprenne pas une expression proche de
Code : Sélectionner tout
[](Type t)->bool{/* ce qu'il faut faire */};
, même s'il y a une paire de crochets en plus

Même pour un programmeur C ca va devenir compliqué.
Ah oui, en C, les expressions lambda n'existent à mon sens pas encore

Mais C++ est beaucoup plus proche (malgré toutes les différences qu'il a par rapport à java) de java que de C, contrairement à ce que l'on croit

Donc, en effet, je raffole pas de ce C++ moderne, surtout dans ses dernières versions.

Chaqun verra midi à sa porte

Je trouve qu'il ajoute de la complexité à la complexité.
Au contraire, je te dirais bien que les versions de C++ d'après 2011 font tout pour essayer de supprimer une partie de la complexité, ou, du moins, pour arriver à en cacher une grosse partie

Sans parler des messages d'erreurs qui font 3 pages.
Les messages d'erreurs qui font trois pages ont toujours été dus à l'approche générique du C++. Enfin, je vais préciser:

Quand une seule erreur provoque un message d'erreur de trois pages, tu dois t'attendre à ce que ce soit du à une erreur en programmation générique.

Que tu aies 120 "faux positifs" après la seule erreur réelle de ton code, parce que le compilateur a "perdu les pédales" mais qu'il a malgré tout essayé de terminer le traitement de ton fichier d'implémentation, ca ca a toujours été

Mais même là, les nouvelles fonctionnalités tendent de résoudre le problème (je pense, entre autres, au static_assert) en faisant apparaitre en priorité un message plus clair et plus précis .

J'aurais préféré qu'on fasse évoluer le langage lui même, par exemple en ajoutant de la granularité,
Je suis mal réveillé, je ne vois pas trop de quoi tu parles...
des pointeurs de fonctions membre directement intégrés au langage sans passer par la lib,

Cela existe depuis toujours, même si ce n'est pas très utilisé
des property comme le C#
Quoi des get et des set automatiques Quelle horreur !!!!
et pourquoi pas une lib graphique
Figure toi qu'il semblerait que ce soit en cours
plutôt que de charger la lib de notions de plus en plus techniques.

La seule notion spécifique à la bibliothèque qui ait été rajoutée (en dehors de certaines classes dont on avait un réel besoin, comme les thread, la gestion du temps ou l'alléatoire), ca a été la sémantique de déplacement.

Et même la sémantique de déplacement représentait un besoin vraiment réel en termes de performances

Ca me fait penser que j'utilise pas non plus les std::string. Bon je suis programmeur win32 c'est 100% de pointeurs et autres LPCTSTR et c'est mieux je trouve.
Encore une fois, chacun verra midi à sa porte, mais LPCSTR
  1. c'est du C
  2. c'est absolument non portable

Dans un monde où windows n'est clairement plus le seul système d'exploitation utilisé, le deuxième point est particulièrement dommage

Au passage, pourquoi ne pas te tourner vers Qt, si tu fait des applications graphiques Il te suffirait d'avoir un compilateur croisé pour que tes applications fonctionnent également sous linux et ou sous mac... cela ne t'intéresse pas

Si ça persiste je pense pas aller vers du Rust, du Swift ou du GO mais plutôt vers le C.
Et tu te retrouveras avec un tas de problèmes encore bien pire que ceux auxquels tu es confronté avec java ou avec C++

C a l'énorme avantage d'être la "franqua lingua" du développement. Mais, si tu a l'habitude du C#, ce n'est vraiment pas pareil

Un langage assez simple pour peu qu'il soit correctement écrit et qui donne accès à tout, par contre ça me fera revenir dans la douleur à un langage sans classes et sans namespace, la c'est dur mais qui a dit que la programmation c'était facile?
Et pourtant, tu choisirais le seul langage qui ne propose à la base ni classes ni espaces de noms

Bonne programmation à tous
Cordialement,
Pareillement
8  0 
Avatar de stardeath
Membre expert https://www.developpez.com
Le 24/04/2019 à 12:09
Citation Envoyé par Spleeen Voir le message
Je déplore tout de même le faible nombre de commentaires sur des articles très bien rédigés, sans faute de français et bien sourcé qui méritent la lecture.
quand tu vois la shitstorm que ça a créé, il vaut mieux ne pas commenter ...
il n'y a globalement (pas tous les commentaires, mais bon, une grande partie) pas eu une seule remise en question, c'est direct : "il a critiqué le c++, au pilori".
donc bon, comme je disais dans un autre fil, dans cette époque "moderne" on ne peut plus apprécier quelque chose et être capable d'émettre des critiques sur ce quelque chose.
7  0 
Avatar de darklinux
Membre averti https://www.developpez.com
Le 24/04/2019 à 3:18
Bref , un langage sécurisé " par nature " , cela n existe pas , on la vu avec les deux premières versions de Java . C 'est le travail du développeur ça , à la limite du framework , mais c 'est tout
6  3 
Avatar de lsbkf
Membre habitué https://www.developpez.com
Le 24/04/2019 à 3:48
Citation Envoyé par Bousk Voir le message
Donc oui il y a vérification en debug, et aucune en release, comme tout bon code devrait logiquement faire.
C'est aussi le cas dans GCC (à voir dans quels cas la macro _GLIBCXX_ASSERTIONS est définie), et il y a des chances pour que LLVM soit aussi dans le coup. Mais évidemment c'est plus facile de taper sur C++ dans un billet de blog !
6  0 
Avatar de ShigruM
Nouveau Candidat au Club https://www.developpez.com
Le 24/04/2019 à 8:06
Citation Envoyé par Spleeen Voir le message
Je déplore tout de même le faible nombre de commentaires sur des articles très bien rédigés, sans faute de français et bien sourcé qui méritent la lecture.
peut etre parcequ'il n'ya rien a commenter...
L'article parle juste d'un haineux qui n'aime pas le C++... on vas pas pour autant abandonner le c++ suite a cela... sont article de blog je l'ai déja oublié.
ce genre d'article de "ouain ouains le langage X est pourrie" tu en as pour tous les langages.

Aucun langage n'est parfait, donc tous les langage sont critiquitable donc les gens cherche a les critiquer mais nous somme sau dessus de cela et le mieu c'est d'ignorer ce genre d'article comme je le fait.
voila pouruqoi personne ne commente cela, car cela n'en vaut pas la peine.
6  2 
Avatar de Uther
Expert éminent sénior https://www.developpez.com
Le 24/04/2019 à 19:30
Citation Envoyé par lsbkf Voir le message
C'est qui lui ? Oh un ingénieur. Si c'est un ingénieur, c'est qu'il a forcément raison !!
C'est clair que sortir l'avis d'une personne plutôt lambda, qui n'apporte rien sur un sujet déjà fort connu, je vois pas trop ce que ça fait en news.

Citation Envoyé par lsbkf Voir le message
Blague à part, c'est écrit où que C++ recherchait la sécurité ? operator[] ne vérifie pas les dépassements, pauvre petit chou.
Le problème est justement que c'est trop facile a utiliser pour quelque chose de potentiellement dangereux. Swift ou Rust permettent les accès non contrôlés si nécessaire pour les performances, mais ils sont explicites pour pousser ceux qui les utilisent à se poser la question de la nécessité de les utiliser.
Un problème récurent en C++ est qu'il y a bien des mécanisme qui permettent une utilisation plus sécurisée, mais eux même introduisent de la complexité et peuvent être mal employés sans que l'on s'en rende compte.

Citation Envoyé par lsbkf Voir le message
Et alors, si t'en veux pas tu l'utilises pas, mais après c'est qui qui doit se plaindre de ces applications qui bouffent tout le CPU comme s'ils étaient seuls à s'exécuter.
Ce discours valait quand on compare le C++ à des langages managés comme le Python ou le Java. Mais là on parle plutôt de langages compilés moderne sans runtime comme le Rust (et le Swift) qui a prouvé que l'on peut être a la fois sécurisé et avoir des performance identiques au C et C++.

Citation Envoyé par sergio_is_back Voir le message
Si on cherche la sécurité à tout prix alors il faut éviter d'écrire une seule de code.... Même dans un langage très cadré un développeur peut induire des biais qui seront acceptés par le compilateur et mèneront à la catastrophe...
Bien sur et on peut démarrer un incendie avec un briquet, alors pourquoi ne pas utiliser un lance flamme pour allumer sa cigarette ?
Ce n'est pas parce qu'aucun langage n'est parfait qu'il n'est pas intéressant de considérer leurs avantages particuliers.

Citation Envoyé par wolinn Voir le message
On peut toujours construire des exemples pour mettre en évidence la faible sécurisation du langage, mais en pratique, c'est un problème surtout pour les débutants ou les programmeurs peu rigoureux
Non c'est clairement un problème qui concerne tous les programmeur. On retrouve en permanence des failles, qui ne seraient pas arrivées avec des langages plus sécurisés, dans tous les navigateurs, OS, et autre programmes critiques, qui ne sont pourtant pas codés par des débutants, et qui sont très surveillés niveau sécularité.

Citation Envoyé par wolinn Voir le message
ou peut-être dans des contextes où on demande aux gens de produire du code au kilomètre le plus vite possible et sans grande contrainte pour les performances du produit final.
Le "peut-être" me parait inadapté car je ne connais quasiment aucune entreprise où le temps n'est pas une contrainte forte.

Citation Envoyé par wolinn Voir le message
Pour ce qui est des 'lambda', c'est une construction nouvelle (bien que ça ait déjà 8 ans), je considère que je n'en maitrise pas encore toutes les subtilités, et donc j'évite simplement les constructions trop audacieuses pour l'instant. Après tout, j'écrivais en C++ presque 20 ans avant que ça existe. Et puis il faut aussi un peu de temps pour avoir confiance dans les compilateurs eux-mêmes.
C'est là où la sécurité est aussi utile à la productivité. En Rust (je connais bien moins Swift) on peut utiliser les lambda sans risques. Au pire le compilateur te dira si ça pose le moindre problème de sécurité.

Citation Envoyé par sebastiano Voir le message
C'est malheureusement devenu une habitude, un monde de plus en plus binaire alors que, paradoxalement, on a un accès à des méthodes, un savoir, des possibilités infiniment plus grandes que ce qu'ont eu nos ancêtres... c'est le monde, c'est comme ça, on ne peut rien y faire.
Je pense que c'est justement un réflexe assez naturel, face à un monde toujours plus vaste au point qu'il peut paraître nous échapper. On peut facilement être tenté de se replier sur ce qu'on connaît, pour avoir un sentiment de sécurité, quitte a passer a coté de beaucoup de choses intéressantes.

Citation Envoyé par Bousk Voir le message
En gros ces langages intègrent dans leur compilateur / phase de compilation de l'analyse de code.
C'est cool, mais en C++ tu as des outils externes qui le font également. C'est loin d'être parfait - mais peuvent-ils prétendre que celui intégré à Rust ou Swift (ou n'importe quel autre nouveau langage qui vient clâmer sa sécurité "by design" le soit ? - mais y'a donc pas de manque réel. Après s'ils sont pas utilisés...
Les créateur de C++ ont travaillé sur une version les "c++ core guidelines" qui permettent au C++ d'être vérifié statiquement sur l'utilisation de la mémoire. C'est bien, mais niveau garanties ça reste loin de ce que peux faire le Rust qui garantit complètement l'absence d'erreur mémoire et de data race. Le C++ n'a pas été du tout prévu pour ça à la base.
6  2 
Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web