|
Publicité ' | ||||||||||||||||||||||||
|
|
#41 | |||||||
|
Inscription : janvier 2011 Messages : 30 ![]() |
Citation:
J'ai dû me creuser les méninges pour trouver un équivalent pratique, et après avoir examiné beaucoup de langages je suis arrivé à la solution suivante : - ajout d'un attribut 'byte qui permet de convertir tous les types "paqués" en tableau de byte. - conversion implicite de tous les types "paqués" en tableau de byte (donc byte[]) lors du passage de paramètres. En clair, ces 2 règles permettent les choses suivantes : Code :
Code :
ils ne peuvent pas contenir de pointeur sécurisé (donc p^). Cela n'est pas gênant car il est rare de devoir sauver un pointeur sur disque .. On peut donc écrire : Code :
|
|||||||
|
|
00
|
|
|
#42 | |||||
![]() ![]() Inscription : juin 2002 Messages : 2 034 ![]() |
Citation:
Sinon une petite question concernant la gestion du passage de la structure INFO dans ton cas de figure, empiles-tu toute la structure lors de l'appel de fonction ou seulement son adresse mémoire ? |
|||||
|
|
00
|
|
|
#43 | |
|
Expert Confirmé Sénior
![]() Inscription : janvier 2007 Messages : 9 569 ![]() |
Citation:
ok, mais quid des utilisations comme "any function" ? (exemple, la fonction de comparaion de qsort, ou les callbacks).. ça ne peut pas être traité comme "un tableau de byte", si ?
__________________
"Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle". Consultant indépendant. Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie. C, Fortran, XWindow/Motif, Java Je ne réponds pas aux MP techniques |
|
|
|
10
|
|
|
#44 | ||||||||||
|
Inscription : janvier 2011 Messages : 30 ![]() |
Citation:
Citation:
Pour les algorithmes comme les tris j'ai été quasiment obligé d'ajouter les packages génériques au langage, ce qui permet de paramétriser un type quelconque pour un algorithme donné (= inspiré des packages génériques Ada, des templates C++, des génériques C#, mais en simplifiant très fort et en séparant bien interface et corps de package). Chaque instantiation générique génère alors du code spécialisé pour le type donné, ce qui est comme j'ai pu le constater par des essais pratiques, très efficace. (j'oserais presque dire plus efficace qu'en C parce que la routine qsort ne doit pas appeler la fonction de comparaison par un appel indirect mais peut utiliser un appel direct, les appels indirects comme vous le savez sans doute étant très mal supportés par le Pentium puisqu'ils vident la queue des instructions, provoquant des pénalités importantes - oui j'ai beaucoup lu les manuels d'Intel c'est très instructif pour optimiser et choisir les instructions rapides, tenir compte des tailles de cache, etc ..) Un autre besoin pour void* se fait sentir quand on écrit un compilateur : en effet quand on crée une représentation syntaxique des instructions par un gigantesque arbre chainé avec des pointeurs dans tous les sens, on doit représenter des structures pointant vers une multitude d'autres structures. Presque tous les langages que je connais ont résolu ce problème en utilisant le concept de 'classe', ainsi que 'classe dérivée'. Cependant je ne voulais pas de ce concept en Safe-C vu la complexité abstraite qu'il génère pour la compréhension des programmes et les pénalités à l'exécution, surtout en cas de conversion d'un type dérivé vers un autre. Une fois qu'on introduit les classes dans un langage ce sont les casse-têtes assurés pour la suite : constructeurs, destructeurs, classe abstraite, etc .. et une multitude d'autres concepts qu'on est pratiquement obligé d'ajouter (voir problèmes rencontrés par les designers du C#). Donc j'ai choisi une autre voie, plus simple : les struct avec discriminant donc j'ai déjà parlé, je remets ici un exemple : Code :
Le discriminant peut être dynamique aussi si l'objet est réservé sur le heap : Code :
Les callbacks sont traités comme en C, on peut créer des pointeurs vers fonctions, les paramètres doivent être compatibles : Code :
p.s: la syntaxe est volontairement brute ici, on peut écrire aussi : Code :
|
||||||||||
|
|
00
|
|
|
#45 | ||||||
|
Inscription : janvier 2011 Messages : 30 ![]() |
j'ai dis plus haut qu'il n'y a pas de classes en Safe-C, en fait il y en a quand même mais des classes ultra-simplifiées : les types opaques.
Ce sont des types qu'on déclare par : dans p.h : Code :
Code :
L'utilisateur de P peut écrire ceci : Code :
Il n'y a pas de constructeur pour un type opaque (car les constructeurs imbriqués c'est une chose horrible qui ralentit beaucoup les programmes), on peut uniquement initialiser l'objet, soit à zéro avec la commande clear, soit en le passant à une fonction avec paramètre 'out'. |
||||||
|
|
00
|
|
|
#46 | |
|
Membre Expert
![]() Inscription : avril 2008 Messages : 794 ![]() |
Bonjour,
d'abord, je suis impressionné par le travail que tu as fait! J'espère juste pour toi que ce n'est pas en vain. Au pire, si personne n'est intéressé, tu pourras toujours l'utiliser pour ton propre travail de développement! Citation:
Je trouve d'ailleurs que ce serait une bonne chose que tout programme soit suffisamment testé (et "purifié") avec ces outils avant d'être distribué! )jack( |
|
|
|
00
|
|
|
#47 | |||||
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Citation:
Citation:
Ensuite cyclone a fait le choix de ne pas offrir la possibilité d'être unsafe. Ca évite d'avoir un peu trop vite la tentation de commencer tous ses fichiers par #pragma unsafe, et en plus ça a poussé les designers du langage à trouver le plus possible de solution pour les situations les plus courantes en C. Bien sûr, il est impossible d'avoir la même flexibilité que quand on a zéro limite comme en C, mais ils sont arrivé à un compromis pas dégueu me semble-t-il. Une des limitations principale à mon sens (parce qu'elle ne se limite pas à des différences de performance) est la gestion de la mémoire. Je pense que pour un grand nombre d'applications, les allocations/désallocations étant bien parenthesé, l'approche par région est fondamentalement la bonne (et avec un bon allocateur, peut même donner des meilleurs performances que malloc/free utilisé "naïvement".) Beaucoup d'application ne respectant pas ce "bon parenthesage" resteront sans doute dans le domaine d'application du pointeur unique (je n'ai pas encore lu cette partie du manuel, mais je pense que c'est juste un pointeur sans alias, que l'on peut donc libérer sans contrainte) En revanche, dès qu'il faut allouer dans le tas principal (la région `H), il faut se reposer sur un GC conservatif, et là il y a inévitablement risque de fuite de mémoire (en plus évidement de l'aspect performance). Citation:
Un autre choix de Cyclone est aussi d'ajouter des exceptions à C. Ce qui permet de ne pas juste arrêter le programme avec un message d'erreur en cas de déréférencement d'un pointeur hors borne. Citation:
Sur la partie compilation pure, j'insiste encore, mais quelle genre d'optimisation as tu ? Parce que "lire la doc intel pour trouver la bonne instruction", c'est bien, mais si tu n'as pas de propagation des constantes ou d'élimination des sous expression communes, ou encore d'inliner,c'est sans doute pas bien utile... Citation:
|
|||||
|
|
00
|
|
|
#48 |
|
Inscription : janvier 2011 Messages : 30 ![]() |
je vais rédiger un texte qui décrit les grandes lignes du Safe-C pour programmeurs expérimentés, en commençant par les concepts et en terminant par les détails. C'est vrai que ce n'est pas évident de cerner un langage sans avoir une base de travail, et le manuel de normalisation que j'ai actuellement est un peu trop indigeste à lire, et il n'explique pas les concepts ..
|
|
|
00
|
|
|
#49 |
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
|
|
|
00
|
|
|
#50 |
|
Inscription : janvier 2011 Messages : 30 ![]() |
voilà, ouf terminé !
Un tutorial Safe-C pour programmeurs expérimentés : ---> http://newchatrooms.dyndns.dk:12000/...AL/manuel.html j'aurai dû commencer par cela, cela m'aurait évité pas mal de questions dans tous les sens .. |
|
|
00
|
|
|
#51 | |||
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Citation:
Un premier commentaire: ton blabla initial est passablement inutile et à même de crisper les gens pas tout à fait d'accord avec toi Déjà, un langage antique et toujours utilisé aujourd'hui : le lisp. Nettement plus vieux que le C Ensuite tu dis "un programme est fiable si quand il crash, ce n'est pas de sa faute". Un programme qui crash n'est *pas* un programme fiable. Ensuite, tu dis "langage fiable == langage qui vérifie que les accès sont dans les bornes". Disons que la vérification des bornes est le minimum du minimum vital d'un langage "fiable". La fiabilité d'une application ne se résume pas à "on n'a pas de corruption mémoire". Va essayer d'expliquer à une autorité de certification que ton avion peut voler sans problème par ce que "on est sur qu'il n'y a pas d'accès en dehors des bornes".. Ensuite, tu dis que les langages modernes sont tous "10 fois plus gros et complexe que le C". Qu'est ce que tu entends par là ? Parce que si tu compare la norme du C à la norme de SML par exemple (Standard ML, langage fonctionnel de la famille Caml), tu te rendras vite compte que le C est *beaucoup* plus complexe que SML, rien qu'au nombre de page. Pour comprendre le C, tu dois maitriser son modèle mémoire, et rien que ça, ça en fait un langage d'une complexité effroyable. Finalement tu dis que "En clair : avec le Safe-C vous avez un langage un tout petit peu plus lent que le C afin de pouvoir satisfaire l'objectif 1 de fiabilité, mais qui reste le plus rapide qu'il soit possible de faire avec cet objectif.". Le fait qu'en restant dans la partie "safe" du safe-C, on soit obligé de se trimbaler des pointeurs "vérifié" montre que cette affirmation est fausse. Je suis près à parier ce que tu veux que Cyclone est plus rapide que ton safe-C sur plein d'application où on peut trivialement éviter les fat pointers Puisque ton seul objectif est la sureté, pourquoi forcer l'initialisation des valeurs ? Seuls la non initialisation des pointeurs pose un soucis. En C, le chiffre derrière int est le nombre de bit, toi d'octet. C'est confusant. Le mécanisme de "Tombstone" me semble assez étonnant. Si je comprends bien, à partir du moment où tu as créé un pointeur, sa "Tombstone" restera là pour toujours. Donc en gros, si je fais Code :
Embêtant non ? Est ce que tu as un lock par tombstone pour être thread safe ? Je suis vraiment désolé, je continue à penser que c'est un travail impressionnant, mais qu'il n'apporte rien d'intéressant par rapport à des projets existant, tels que Cyclone :-\ |
|||
|
|
10
|
|
|
#52 |
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Je viens de penser à des problèmes potentiellement encore plus graves avec tes "tombstones". Est ce que tu peux nous faire une description plus poussée de ce que tu fais ? La vraie structure mémoire, et ce qu'il se passe à run time, en particulier l'arithmétique de pointeurs.
Merci ! |
|
|
00
|
|
|
#53 | |||||||||
|
Inscription : janvier 2011 Messages : 30 ![]() |
Citation:
Citation:
Citation:
--------------------------- tu parles toujours des fat pointers de Cyclone, est-ce que ce sont des structures composées d'un pointeur et d'une taille ? Que se passe-t-il si 2 threads accèdent à cette structure en même temps, par exemple une assignation d'une valeur pointeur à une variable fat pointer, ne risquent-ils pas de la corrompre ? En Safe-C je voulais expressément des pointeurs de la taille d'une adresse mémoire pour que les assignations de pointeurs soient naturellement thread-safe. ---------------------------- Citation:
Le problème c'est que si je renonce à l'initialisation des variables, je ne sais plus introduire les nouveaux modes de passage de paramètres. D'autre part, avoir des variables non-initialisées crée des programmes qui ne se comportent pas d'une manière déterministe, ce qui complique fortement la recherche d'erreurs. Il faudra peut-être que je nuance ma définition de 'safe' .. Citation:
Code :
Citation:
Citation:
moi je pense à des problèmes graves avec tes fat-pointers. :-) |
|||||||||
|
|
00
|
|
|
#54 | ||||
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Qui programme encore avec le C de l'époque plutôt qu'en C 90 voir 99 ?
Citation:
Citation:
Citation:
Citation:
Tout le monde n'a pas windows. C'est pour ça que j'aimerais une description plus fine de tes tombstones. Du peu que tu as dit, je ne vois comment ta structure intermédiaire peu disparaitre, ni comment peut fonctionner l'arithmétique de pointeurs. J'ajouterai que mettre un lien vers ton petit projet perso sur wikipedia est assez déplacé. Je suggère fortement que tu le supprimes. |
||||
|
|
00
|
|
|
#55 | ||
|
Inscription : janvier 2011 Messages : 30 ![]() |
Citation:
C'est l'auteur d'une note "white paper" qui en parlant de pointeurs m'a donné l'idée qu'en fait on ne risquait pas de corrompre la mémoire si on réutilisait le slot tombstone pour le même "type" d'objet heap. Le tombstone retient donc vers quel type d'objet il pointe. En ce qui concerne l'arithmétique de pointeurs, elle n'est tout simplement pas autorisée. p.s: j'ai complètement enlevé l'introduction, donc le texte passe directement au coeur du sujet, c'est beaucoup mieux en effet Citation:
|
||
|
|
01
|
|
|
#56 |
|
Membre chevronné
![]() Inscription : mars 2010 Messages : 281 ![]() |
Bon, je suis désolé, mais ceci achève de détruire définitivement toute crédibilité à ton "langage". Dire que c'est "exactement comme le C sauf que c'est safe", alors que tu n'autorise pas l'arithmétique de pointeur, je suis désolé, mais c'est une grosse blague. Il reste quoi comme intéret au C par rapport aux autres langages si tu ne peux pas faire d'arithmétique de pointeur ?
|
|
|
10
|
|
|
#57 |
|
Inscription : janvier 2011 Messages : 30 ![]() |
il faut poser la question autrement : comment cyclone rend-il l'incrémentation de pointeurs sûre ? en vérifiant chaque fois que le pointeur est toujours dans une zone mémoire donnée, par deux tests : p >= début && p < début + longueur. Il est bien plus économique d'utiliser un tableau et de ne faire qu'un seul test non-signé sur l'indice. En résumé : l'incrémentation de pointeur safe n'a plus aucun avantage sur les indices de tableaux.
|
|
|
00
|
|
|
#58 | ||||
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Bonjour,
Voici mon premier programme de test. En Safe-C : Code :
Code :
C# : 00.580 s Safe-C : 09.838 s Je retourne donc utiliser un langage "lourd et lent avec son garbage collector" (en vrai, j'utilise peu C#, mais c'était pour répondre à vos accusations). |
||||
|
|
50
|
|
|
#59 |
|
Inscription : janvier 2011 Messages : 30 ![]() |
touché ...
apparemment j'ai encore pas mal de boulot pour optimiser les boucles .. |
|
|
00
|
|
|
#60 |
|
Membre Expert
![]() Inscription : mars 2002 Messages : 962 ![]() |
Pour information, C# n'effectue pas de test sur l'indice quand il se rend compte statiquement que ça ne sert à rien. Si je boucle de 0 à Length, on sait qu'on ne dépasse pas du tableau. C'est une optimisation parmi beaucoup d'autres.
J'espère que le compilateur remplace tous les arr'length par sa valeur, qui est connue statiquement. J'espère aussi que la boucle est effectuée l'envers (comparer un entier avec 0 est plus rapide qu'avec length), puisque le résultat ne change pas. J'espère que le clear ne fait rien, puisque je mets à 2 ensuite... Je serais admiratif si vous réussissez à battre C# en écrivant votre propre génération de code. C'est pour cette raison que j'ai conseillé dès le départ d'utiliser un backend éprouvé, comme LLVM. Vous pouvez aussi générer du code C et appeler un compilo C. |
|
|
20
|
Copyright © 2000-2013 - www.developpez.com