IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

Nouveau langage : le Safe-C


Sujet :

Contribuez

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut Nouveau langage : le Safe-C
    Bonjour au forum,

    passionné de C depuis plus de 10 ans et ayant l'habitude des gros programmes de plus de 50,000 lignes, cela m'a toujours embêté d'avoir autant de difficultés pour trouver et corriger les bugs, le C ne vérifiant ni les indices de tableaux, ni les pointeurs.

    J'ai envisagé de passer au C++ ou au C#, mais ni l'un ni l'autre ne me satisfont vraiment : le C++ ne vérifie pas plus les indices et les pointeurs que le C, et le C# ne génère pas du vrai code assembleur et en plus est lourd et lent avec son garbage collector.

    Bref, une seule solution restait : créer mon propre langage qui ressemblerait très fort au C et en garderait la vitesse que nous apprécions tous, mais en même temps le transformer pour qu'il ne soit plus possible qu'une partie du code écrive en mémoire où il ne peut pas ...

    Je l'ai baptisé le Safe-C, je pense que cela résume bien ce que c'est.

    Pendant tout 2010 j'ai écris les spécifications du langage ainsi qu'un compilateur Safe-C pour Windows; maintenant en 2011 je suis en train d'écrire les librairies.

    C'est un vrai langage où on peut faire tout ce qu'on peut faire aussi en C, mais si l'un des indices de tableau déborde ou qu'un pointeur écrit où il ne peut pas, vous aurez tout de suite une erreur qui vous indique où dans le code source il y a problème, d'où énormément de temps gagné en développement.

    Si quelqu'un ici a envie de participer à cette aventure (il y a encore beaucoup à faire : écrire des librairies, des tutorials, proposer des modifs) il est le bienvenu Il faut qu'il connaisse bien le C parce que le Safe-C en est très proche.

    J'ai mis un premier tutorial pour débutants en informatique sur ce site provisoire : http://newchatrooms.dyndns.dk:12000/...IAL/start.html

    Je suis en train d'écrire des librairies faciles à utiliser pour IPV4 et IPV6, d'autres suivront ..

    Pour me contacter c'est marcsamu@hotmail.com

    Si cela rencontre du succès on pourra peut-être ouvrir une rubrique ici sur le forum ..

  2. #2
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Marc.Samuro Voir le message
    le C++ ne vérifie pas plus les indices et les pointeurs que le C
    As-tu entendu parlé de std::vector (et autres containers standards), std::string, smart pointer, référence, etc. ?

    Même si le C++ n'est pas parfait à ce niveau là, dire qu'il n'apporte rien de plus que le C c'est quand même assez gros.


    Sinon concernant ton langage, quelques questions suite à ta présentation :
    • Tu dis que les indices et pointeurs sont vérifiés par le langage, mais comment ? A quel moment (compile time ou run time) ? Que se passe-t-il précisément en cas d'erreur ? Jusqu'à quel point le comportement peut-il être configurer ?
    • Pourquoi ne pas avoir choisi une politique où les tableaux gèrent leur taille et sont capables de se redimensionner lorsque nécessaire (particulièrement en ce qui concerne les chaînes de caractères) ?
    • Es-tu capables de t'interfacer avec d'autres langages (notamment le C) ? Si oui, comment ?

  3. #3
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    - Qu'en est-il de l'interopérabilité avec le C ?
    - Que pensez-vous de D ?
    - Quel est votre modèle de compilation ? Générez-vous du code C, appelez-vous un back-end existant (comme LLVM) ou générez-vous directement le code binaire ?
    - Qu'en est-il des performances (vous semblez attaquer C#, mais c'est bien plus optimisé que ce que vous semblez croire) et de la portabilité ?
    - Peut-on utiliser des outils existants (IDE, débogueurs...) avec votre langage ?

    J'ai envisagé de passer au C++ ou au C#, mais ni l'un ni l'autre ne me satisfont vraiment : le C++ ne vérifie pas plus les indices et les pointeurs que le C, et le C# ne génère pas du vrai code assembleur et en plus est lourd et lent avec son garbage collector.
    C++ vérifie les accès aux vecteurs, strings, etc. Du C++ correctement utilisé vérifie beaucoup de choses et est beaucoup plus sûr que le C. C# génère du vrai code natif à la volée (ce qui présente beaucoup d'avantages).

    Il existe déjà beaucoup de dérivés du C, la plupart d'entre eux ayant essayé de corriger les problèmes de sûreté. N'y en a-t-il vraiment pas un qui vous satisfasse ? Créer un énième langage, ne proposant quasiment rien de nouveau, me semble totalement voué à l'échec.

  4. #4
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 379
    Points
    20 379
    Par défaut
    Je suis totalement d'accord avec Gl les conteneurs du C++ donnent entièrement satisfaction pas besoin d'être un expert du C++ pour les utiliser
    Et puis il y a Boost aussi ( intégrée à Visual Studio 2010 )

    Citation Envoyé par Marc.Samuro Voir le message
    et le C# ne génère pas du vrai code assembleur et en plus est lourd et lent avec son garbage collector.
    là aussi je suis d'accord ( ce n'est pas le sujet ) J'ai une certaine aversion pour tout ce qui est .NET

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    réponse à ql:

    Q1:
    c'est clair que les librairies string, vecteur, etc.. du C++ apportent une sécurité, mais elle est limitée à ces type de données (string ou vecteur).

    En Safe-C je voulais une sécurité à 100%, même pour les simples tableaux, même pour les printf, les passages de paramètres, pointeurs, etc ... il n'y a pas de faille.

    Il est cependant possible de créer des pointeurs non-vérifiés comme en C en utilisant les pragma "#begin unsafe" et "#end unsafe". C'est nécessaire pour interfacer avec Windows.

    Q2:
    Les pointeurs sont vérifiés à l'exécution pour un mécanisme de tombstone (voir wikipedia).
    C'est vrai que c'est plus lent que des pointeurs classiques, mais :
    - cela offre une sécurité à 100% : cela vérifie les pointeurs non valides, les double-free, tous les cas sont prévus.
    - c'est scalable (donc ne ralentit pas pour les gros programmes contrairement aux langages qui utilisent un garbage collector).
    - on utilise beaucoup moins les pointeurs en Safe-C que dans les langages qui ont des classes, donc un léger ralentissement ne se remarque pas.

    Q3:
    en cas d'erreur le programme se plante à l'endroit de l'erreur. Donc il n'écrase pas de données plus loin et ne peut pas écraser la pile. On a directement l'endroit de l'erreur et on peut corriger, donc c'est mieux qu'en C. En tant que programmeur C le mécanisme d'exception du C++ me semble trop lourd et bon, le but ici est de n'avoir aucune exception.

    Q4:
    Le safe-C reprend la plupart des éléments du C, et les strings dynamiques n'en font pas partie.

    Q5:
    pour le moment je peux m'interfacer avec des DLL windows, j'en suis à la version 1 du compilateur.

    réponse à LLB:
    Q1: l'interopérabilité est, disons, faisable. Actuellement je suis en train de reprendre toutes mes anciennes librairies source C et de les adapter, cela va quand même assez vite.

    Q2: je ne connais pas D mais c'est OO je pense ?

    Q3: le compilateur Safe-C génère du bon vieux code machine 32-bit pour Windows (processeur Intel/Amd) (je n'ai pas inclus les instructions SSE parce que tous le monde ne les a pas). Le compilateur est déjà prévu pour générer du 64-bit, ce sera pour plus tard.

    Q4: les performances sont aussi bonnes qu'en C. Les vérifications d'indice de tableau ne génèrent que 2 instructions assembleur en plus, cela ne se remarque même pas.

    Q5: non pas encore de debugger, je suis à la version 1 là.


    Bon vous avez tous l'air de tirer à boulets rouge dessus, c'est vrai que ce langage ne propose rien de révolutionnaire. C'est un dérivé du C qui propose plus de sécurité et en profite pour améliorer 2 ou 3 choses. Le langage reste petit et simple comme le C, il n'y a pas de quoi brandir les fourches et de tout brûler hein .

    - Peut-on utiliser des outils existants (IDE, débogueurs...) avec votre langage ?

    ah des outils existants ! oui on peut, en fait j'utilise le debugger de visual C pour le moment. Mais j'ai écris une librairie d'exception qui redirige le vecteur d'exception de windows, donc en cas de plantage ça m'affiche directement l'endroit dans le source, c'est pratique. Je n'ai pas encore d'IDE, je travaille en Dos là.

    Le but du Safe-C est qu'il ne soit pas possible qu'une partie d'un programme écrase les données d'une autre partie du programme en dehors des règles du langage : les indices de tableau sont vérifiés, les pointeurs passent par des tombstone, les strings ont un byte 0 optionnel et non obligatoire comme en C, les fonctions à nombre variable de paramètres créent un tableau sur la pile avec les paramètres variables et seul l'adresse du tableau est passée.

    Il y a beaucoup de vérifications à la compilation : tout doit être initialisé, même les tableaux (il y a d'ailleurs une commande 'clear' pour effacer une variable), le compilateur vérifie aussi que le string "%s%d" d'un printf correspond aux arguments si celui-ci est constant, ce qui évite d'avoir des erreurs à l'exécution. Bref, le Safe-C reprend tous les éléments du C et les rend sûrs.

    Il y a 2 ou 3 choses nouvelles seulement : un type "opaque" qui est la même chose que "struct" mais les champs du struct ne sont pas visible dans d'autres fichiers. (encapsulation de données); des packages génériques aussi (l'équivalent des templates du C mais simplifiés à l'extrème; tout se passe à la compilation, cela remplace en fait les macros du C).

  6. #6
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Bon vous avez tous l'air de tirer à boulets rouge dessus, c'est vrai que ce langage ne propose rien de révolutionnaire.
    Oui, et c'est le problème. C'est très dur de populariser un nouveau langage. En général, un langage ne marche que s'il est vraiment novateur (et se démarque du reste) ou s'il est poussé par une entreprise (ou université, centre de recherche).
    Si quelqu'un veut utiliser ce nouveau langage, quelle garantie a-t-il qu'il sera toujours maintenu dans 5 ou 10 ans ?

    Après, il ne faut pas prendre les critiques mal, ça permet de mieux se rendre compte des qualités ou défauts du langage. Pour ma part, ça doit être le 10e langage que je croise qui souhaite corriger les défauts du C. Personnellement, pour avoir travaillé professionnellement sur la conception et l'implémentation de nouveaux langages, je sais à quel point c'est difficile d'en populariser un. Écrire un compilateur qui marche n'est pas le plus dur.

    Q2: je ne connais pas D mais c'est OO je pense ?
    Oui (un peu comme en C++). Voir ici
    Disons que ça reprend des idées du C++, en enlevant un certain nombre de problèmes (car ils n'ont pas gardé la compatibilité avec le C). Un peu moins de puissance qu'en C++ (templates plus simples, par exemple), mais c'est plus sûr et plus simple.

    Q1: l'interopérabilité est, disons, faisable. Actuellement je suis en train de reprendre toutes mes anciennes librairies source C et de les adapter, cela va quand même assez vite.
    Il faut réécrire le code ? Si on veut utiliser DirectX, OpenGL ou toutes les autres bibliothèques populaires, ça représente beaucoup de travail ?

    Q3: le compilateur Safe-C génère du bon vieux code machine 32-bit pour Windows (processeur Intel/Amd) (je n'ai pas inclus les instructions SSE parce que tous le monde ne les a pas).
    Tandis que le JIT de C# est capable d'utiliser les SSE quand c'est disponible (c'est un avantage du JIT). Générer du code efficace n'est pas simple, il y a énormément d'optimisations à faire. Même si C# n'a pas de performances optimales (parce qu'il fait de l'introspection, garde les infos de type à l'exécution, parce que le JIT ne peut pas prendre 10s pour optimiser...), ça m'intéresse de voir des benchmarks avec votre compilateur.

    Cela m'intrigue : pourquoi ne pas utiliser un backend existant ? Pourquoi ne pas utiliser par exemple LLVM ? Vous avez vraiment envie de réécrire la génération de code pour chaque architecture à gérer ? La portabilité est quand même l'un des gros avantages du C, il ne faudrait pas l'oublier.

    Les vérifications d'indice de tableau ne génèrent que 2 instructions assembleur en plus, cela ne se remarque même pas.
    Les compilateurs existants (comme en C#) sont capables de ne pas faire la vérification d'indice dans de nombreux cas (grâce à une analyse statique du code).

    En tant que programmeur C le mécanisme d'exception du C++ me semble trop lourd et bon, le but ici est de n'avoir aucune exception.
    Lourd à quel niveau ? Je trouve que la gestion d'erreurs est bien plus lourde à faire correctement en C qu'en C++.

    En Safe-C je voulais une sécurité à 100%, même pour les simples tableaux
    Que se passe-t-il si on accède hors d'un tableau (avec un indice variable) ? Ne pensez-vous pas que lancer une exception serait la bonne chose à faire dans ce cas ?

    Il y a beaucoup de vérifications à la compilation
    Les compilateurs C sont déjà capables de vérifier le format d'un printf quand il est connu ou vérifier que les variables sont initialisées (dans les cas simples).

    c'est clair que les librairies string, vecteur, etc.. du C++ apportent une sécurité, mais elle est limitée à ces type de données (string ou vecteur).
    Les références sont aussi plus sûres que les pointeurs.

  7. #7
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Marc.Samuro Voir le message
    Bon vous avez tous l'air de tirer à boulets rouge dessus, c'est vrai que ce langage ne propose rien de révolutionnaire. C'est un dérivé du C qui propose plus de sécurité et en profite pour améliorer 2 ou 3 choses. Le langage reste petit et simple comme le C, il n'y a pas de quoi brandir les fourches et de tout brûler hein .
    Non, ma but n'est pas de tirer à boulet rouge. Je cherche simplement à savoir ce que propose ton langage et s'il est susceptible de m'intéresser.
    Au risque de paraître un peu brutal, s'il ne m'apporte rien, il n'y a aucune chance que j'y passe du temps dessus (je n'ai déjà pas assez de temps pour me consacrer à tout les langages, bibliothèques, articles, etc. qui m'intéressent)

    Citation Envoyé par Marc.Samuro Voir le message
    Les pointeurs sont vérifiés à l'exécution pour un mécanisme de tombstone (voir wikipedia).
    C'est vrai que c'est plus lent que des pointeurs classiques, mais :
    - cela offre une sécurité à 100% : cela vérifie les pointeurs non valides, les double-free, tous les cas sont prévus.
    - c'est scalable (donc ne ralentit pas pour les gros programmes contrairement aux langages qui utilisent un garbage collector).
    Et concernant les accès hors borne du tableau ? Également à l'exécution ?
    Pourquoi ne pas chercher à vérifier ce qui peut l'être à la compilation ?

    Citation Envoyé par Marc.Samuro Voir le message
    - on utilise beaucoup moins les pointeurs en Safe-C que dans les langages qui ont des classes, donc un léger ralentissement ne se remarque pas.
    Euh ! Quel est le rapport entre le faite d'avoir des classes et la densité de pointeurs dans un programme ?

    Citation Envoyé par Marc.Samuro Voir le message
    en cas d'erreur le programme se plante à l'endroit de l'erreur. Donc il n'écrase pas de données plus loin et ne peut pas écraser la pile. On a directement l'endroit de l'erreur et on peut corriger, donc c'est mieux qu'en C. En tant que programmeur C le mécanisme d'exception du C++ me semble trop lourd et bon, le but ici est de n'avoir aucune exception.
    Donc un problème implique forcément un crash du programme. Il n'y a pas moyen d'intercepter les erreurs et de les traiter différemment (ce que permettent les exceptions) ?

    Citation Envoyé par Marc.Samuro Voir le message
    Le safe-C reprend la plupart des éléments du C, et les strings dynamiques n'en font pas partie.
    std::string c'est du C++ pas du C. Il n'y a actuellement pas de type string en C.

    Citation Envoyé par Marc.Samuro Voir le message
    pour le moment je peux m'interfacer avec des DLL windows, j'en suis à la version 1 du compilateur.
    Ce qui ne veut pas dire grand chose.

    Peux-tu passer tes tableaux et des pointeurs managés aux APIs systèmes ? Sais-tu recevoir des pointeurs en retour de ces mêmes APIs ? Dans ce cas deviennent-ils safe ? Comment gères-tu le fait de ne pas forcément avoir de \0 terminal dans tes chaînes lorsque tu appelles une fonction qui attends la présence de ce \0 ? Es-tu capables d'appeler des fonctions variadic ? Etc ...

    Citation Envoyé par Marc.Samuro Voir le message
    l'interopérabilité est, disons, faisable. Actuellement je suis en train de reprendre toutes mes anciennes librairies source C et de les adapter, cela va quand même assez vite.
    Qu'appelles-tu "adapter les librairies C" ? Tu ne penses quand même pas à les réécrire en safe-C une par une. Même si unitairement le travail n'est peut être pas énorme (et encore ?), je ne pense pas que porter plusieurs milliers de bibliothèques soit vraiment ce que l'on puisse appeler interopérabilité.

    Citation Envoyé par Marc.Samuro Voir le message
    je ne connais pas D mais c'est OO je pense ?
    Non, c'est multi-paradigme (tout comme le C++). L'OO n'est qu'un des paradigmes supportés.

    Citation Envoyé par Marc.Samuro Voir le message
    le compilateur Safe-C génère du bon vieux code machine 32-bit pour Windows (processeur Intel/Amd) (je n'ai pas inclus les instructions SSE parce que tous le monde ne les a pas). Le compilateur est déjà prévu pour générer du 64-bit, ce sera pour plus tard.
    Ne trouves-tu pas contradictoire de te plaindre des performances de certains langages et en même temps ne pas supporter certaines instructions des processeurs qui permettent d'en gagner ? Surtout lorsque les compilateurs pour ces langages sont eux capables de gérer ces instructions.

    Citation Envoyé par Marc.Samuro Voir le message
    les performances sont aussi bonnes qu'en C. Les vérifications d'indice de tableau ne génèrent que 2 instructions assembleur en plus, cela ne se remarque même pas.
    La question n'est pas tant le coût des instructions supplémentaires pour la gestions des bornes de tableau (bien que dans certains cas, il est possible de ne pas le faire si la vérification est faite à la compilation) mais de savoir si ton compilateur safe-C optimise aussi bien le code que le ferais un compilateur C.

    Citation Envoyé par Marc.Samuro Voir le message
    non pas encore de debugger, je suis à la version 1 là.
    Le problème est qu'il est difficile actuellement de "vendre" un nouveau langage s'il n'a pas un minimum d'écosystème autour.

    Citation Envoyé par Marc.Samuro Voir le message
    Il y a beaucoup de vérifications à la compilation :
    Ce qui est, ama, une bonne chose.

    Citation Envoyé par Marc.Samuro Voir le message
    tout doit être initialisé, même les tableaux (il y a d'ailleurs une commande 'clear' pour effacer une variable)
    Dans les exemples que tu donnes, tout n'est pas initialisé à la création. Par contre tout semble l'être avant la première utilisation. Est-ce bien de cela que tu parles ?

    Certains compilateurs C (par exemple gcc) sont capables de réaliser (enfin dans une certaines mesures, certaines constructions complexes posent problèmes) ce type de tests.

    Citation Envoyé par Marc.Samuro Voir le message
    le compilateur vérifie aussi que le string "%s%d" d'un printf correspond aux arguments si celui-ci est constant, ce qui évite d'avoir des erreurs à l'exécution.
    Là encore gcc (et probablement d'autres compilateurs) effectuent cette vérification pour les fonctions variadic de la bibliothèque standard (dont printf).

    Citation Envoyé par Marc.Samuro Voir le message
    Il y a 2 ou 3 choses nouvelles seulement : un type "opaque" qui est la même chose que "struct" mais les champs du struct ne sont pas visible dans d'autres fichiers.
    Et ce que celà via à la place des structures ou en plus ?
    Quel est l'avantage par rapport à la construction classique en C qui consiste à définir la structure uniquement dans le fichier source qui implémente les fonctions de celle-ci et de simplement fournir une déclaration incomplète dans le header ?

    Citation Envoyé par Marc.Samuro Voir le message
    des packages génériques aussi (l'équivalent des templates du C mais simplifiés à l'extrème; tout se passe à la compilation, cela remplace en fait les macros du C).
    Peux-tu en dire plus (je n'ai rien trouver à ce sujet dans la page que tu as fourni).

    Que peut-on faire avec ? Comment est-ce gérer ?

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    Q: Il faut réécrire le code ? Si on veut utiliser DirectX, OpenGL ou toutes les autres bibliothèques populaires, ça représente beaucoup de travail ?
    R: il faut ré-écrire des interface pour chacune des libraries oui, par exemple actuellement j'appelle des DLL Windows comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #begin unsafe
     
    struct WSADATA
    {
      uint2  wVersion;
      uint2  wHighVersion;
      char   szDescription[256+1];
      char   szSystemStatus[128+1];
      uint2  iMaxSockets;
      uint2  iMaxUdpDg;
      char   *VendorInfo;
    }
     
    [extern "ws2_32.dll"]
    int WSAStartup (uint version, WSADATA *data);
     
    #end unsafe
     
    ....
     
     
    int init_socket_library ()
    {
      WSADATA  wsaData;
     
    #begin unsafe
        if (WSAStartup (0x0202, &wsaData) != 0)   // version 2.2
    #end unsafe
        {
          return TCP_DRIVER_PROBLEM;
        }
     
    ...
    Bref, il faut ré-écrire les include files de Windows pour le langage, mais je suppose que c'est pareil pour tout nouveau langage.

    ----------------------------------------------------------------------

    Q: Tandis que le JIT de C# est capable d'utiliser les SSE quand c'est disponible (c'est un avantage du JIT). Générer du code efficace n'est pas simple, il y a énormément d'optimisations à faire. Même si C# n'a pas de performances optimales (parce qu'il fait de l'introspection, garde les infos de type à l'exécution, parce que le JIT ne peut pas prendre 10s pour optimiser...), ça m'intéresse de voir des benchmarks avec votre compilateur

    Cela m'intrigue : pourquoi ne pas utiliser un backend existant ? Pourquoi ne pas utiliser par exemple LLVM ? Vous avez vraiment envie de réécrire la génération de code pour chaque architecture à gérer ? La portabilité est quand même l'un des gros avantages du C, il ne faudrait pas l'oublier..
    R: il ne faut pas confondre le langage et le compilateur. Bon ici j'ai écris un compilateur pour windows, j'ai essayé d'optimiser au mieux le code généré mais je suis persuadé qu'il y a des spécialistes qui font cela encore mieux que moi.

    D'autres personnes peuvent tout à fait écrire leur compilateur, j'ai rédigé des spécifications techniques très précises qui décrivent le langage en détails afin que les programmes soient tous portables (voir le lien tout en bas sur la page de début du site).

    ----------------------------------------------------------------------

    Q: Que se passe-t-il si on accède hors d'un tableau (avec un indice variable) ? Ne pensez-vous pas que lancer une exception serait la bonne chose à faire dans ce cas ?
    R: En C il n'y a pas d'exceptions, j'ai écris des très gros programmes professionellement et je n'en ai jamais eu besoin, donc pourquoi en ajouter ? Une erreur comme un dépassement d'indice est une erreur grave qui ne devrait
    jamais arriver et qui demande un arrêt du process. Vouloir rattrapper cela par un handler d'exception qui redémarre le programme est une option qu'on peut aussi implémenter en redémarrant le process.

    Beaucoup de langages sont trop gros et complexes, je préfère rester minimaliste, comme le C.

    ----------------------------------------------------------------------

    Q: Et concernant les accès hors borne du tableau ? Également à l'exécution ?
    Pourquoi ne pas chercher à vérifier ce qui peut l'être à la compilation ?
    R: le compilateur vérifie les indices de tableau (et aussi de slices de tableau, =tranches) à la compilation si les indices sont des expressions constantes.

    ----------------------------------------------------------------------

    Q: Quel est le rapport entre le faite d'avoir des classes et la densité de pointeurs dans un programme ?
    R: je précise mon idée : en fait dans les langages OO, quand vous créez une grande variable (classe ou tableau), vous la créez sur le heap. En C (et Safe-C) vous pouvez créer une grande variable structure ou tableau sur la pile, ce qui ne nécessite aucune indirection de pointeur pour y accéder (c'est mov eax,[ebp]offset pour charger un champ d'une struct déclarée comme variable locale) alors qu'en OO vous avez toujours un pointeur sur chaque classe (même si ça ne s'appelle pas pointeur). Il y a donc beaucoup plus de "pointeurs" (ou indirections) en langage OO qu'en C.

    Disons pour parler clairement, les langages OO créent une multitute d'objets sur le heap (pour chaque classe), le C et Safe-C n'en font que si on utilise explicitement des pointeurs.

    ----------------------------------------------------------------------

    Q: Peux-tu passer tes tableaux et des pointeurs managés aux APIs systèmes ? Sais-tu recevoir des pointeurs en retour de ces mêmes APIs ? Dans ce cas deviennent-ils safe ?
    R: bien sûr on sait passer des tableaux aux API. Pour passer l'addresse d'une variable à un API on utilise l'opérateur & comme en C qui permet de prendre l'adresse d'une variable et dont le résultat est un pointeur (non-managé), exactement comme en C. Evidemment le truc c'est que l'opérateur & n'est autorisé qu'à l'intérieur d'une section #begin unsafe .... #end unsafe, donc généralement dans une librairie. Les utilisateurs ne sont pas censés
    utilisés ces sections unsafe ou en tout cas le moins possible, parce qu'avec elles on programme exactement comme en C, sans sécurité.

    Je précise que les pointeurs ne sont pas "managés", les objets ne bougent pas, il n'y pas de garbage collection et il faut faire ses free soi-même (il y un opérateur "new" très riche pour créer même des struct et tableau dynamiques, et une commande free).

    ----------------------------------------------------------------------

    Q: Comment gères-tu le fait de ne pas forcément avoir de \0 terminal dans tes chaînes lorsque tu appelles une fonction qui attends la présence de ce \0 ?
    R: il faut recopier la chaine et ajouter un zéro, pareil qu'en C#, pour tous les APIs qui ont besoin d'un PSTR. J'ai constaté qu'il n'y en a pas tant que cela en pratique dans l'API windows, et aucun pour des fonctions qui doivent être performantes comme read & write.

    //----------------------------------------------------------------------------

    Q: Es-tu capables d'appeler des fonctions variadic ?
    R: oui mais elle ne sont pas passées comme en C. Les addresses et tailles des arguments variables sont tous rassemblés et mis dans un tableau et l'adresse du tableau est passé comme 1 paramètre. Je pense que le C# fait comme cela aussi. L'utilisateur peut donc créer sans problème des fonctions à nombre de paramètres variables comme printf, fprintf, etc .. avec sécurité totale.

    //----------------------------------------------------------------------------

    Q: Qu'appelles-tu "adapter les librairies C" ?
    R: j'ai une collection de librairies source C que je soigne depuis 10 ans, pour tcpip, traitement d'image, ... Je pense qu'en 3 mois j'aurai tout adapté en Safe-C pour que je puisse continuer à programmer dans ce langage. Maintenant n'importe qui peut créer ses propres librairies, c'est comme en C, on peut partir de zéro.

    //----------------------------------------------------------------------------

    Q: Ne trouves-tu pas contradictoire de te plaindre des performances de certains langages et en même temps ne pas supporter certaines instructions des processeurs qui permettent d'en gagner ? Surtout lorsque les compilateurs pour ces langages sont eux capables de gérer ces instructions.
    R: j'écris des programmes qui sont distribués sur internet et qui donc doivent tourner sur toutes les versions de Windows et tous les CPU. Actuellement pour mes librairies je n'utilise que des API à partir de Windows 2000 et aucune instruction SSE. Maintenant il est possible que je propose un petit moteur 3D avec des instructions SSE2 inline (c'est pratique pour multipler 4 float en 1 instruction mais alors avec avertissement que ce n'est pas pour toutes les machines.

    //----------------------------------------------------------------------------

    Q: Dans les exemples que tu donnes, tout n'est pas initialisé à la création. Par contre tout semble l'être avant la première utilisation. Est-ce bien de cela que tu parles ?
    R: oui, toutes les variables doivent être initialisées à la première utilisation. Le compilateur suit le flot des instructions et vérifie cela. C'est très important pour la sécurité. Initialiser un champ d'un struct ne suffit pas pour que le struct soit considéré comme initialisé, il faut soit un "clear", soit une assignation à la variable entière. Le langage a un très bon support pour les constantes (simple, tableau, struct, jagged) ainsi que les aggregates, afin de rendre simple ces initialisations.

    Un exemple:

    date = {day => 1, month => 1, year => 2011};

    //----------------------------------------------------------------------------

    Q: Et ce que celà via à la place des structures ou en plus ?
    Quel est l'avantage par rapport à la construction classique en C qui consiste à définir la structure uniquement dans le fichier source qui implémente les fonctions de celle-ci et de simplement fournir une déclaration incomplète dans le header ?
    R: un type opaque est défini comme ceci dans le .h :

    struct MON_TYPE;

    Dans le .c correspondant, il doit y avoir la déclaration complète :

    struct MON_TYPE;
    {
    int a, b, c;
    }

    Donc évidemment si un autre fichier "importe" le .h il n'a pas accès aux champs.

    Je signale qu'il n'y a pas "d'#include" comme en C, c'est plus un import de libraries comme en C#, ce qui a pas mal d'avantages : l'ordre des imports n'a pas d'importance, il ne faut pas inclure une librairie avant une autre.

    A signaler aussi : le compilateur 'trouve' automatiquement les fichiers à inclure. Si vous faites :

    // main.c

    use sys/mylib;


    Il va chercher un fichier mylib.h dans le répertoire ./sys et le compiler, ensuite il va voir s'il n'y a pas un mylib.c correspondant dans le même répertoire. Bref, plus la peine d'écrire des makefile, le compilateur trouve les fichiers tout seul en suivant les "use" dans chaque fichier.

    //----------------------------------------------------------------------------

    Q: Peux-tu en dire plus (je n'ai rien trouver à ce sujet dans la page que tu as fourni).
    Que peut-on faire avec ? Comment est-ce gérer ?
    R:
    Les packages génériques c'est une idée que j'ai repris du langage Ada en simplifiant.

    En gros : un générique consiste à écrire un morceau de code en "paramétrant" un ou plusieurs "type" que vous ne spécifiez pas. Le compilateur va compiler ce générique en le vérifiant syntaxiquement, mais il ne va pas en générer de code assembleur.

    Une fois écrit, vous pouvez "instancier" ce package en spécifiant des types à la place des paramètres. Lors d'une commande d'instantiation le compilateur va prendre une copie du package générique, remplacer les types paramètres par vos types et générer du code. Tout cela se passe à la compilation. ça ressemble à une macro en C sauf que le package générique est vérifié syntaxiquement. On peut aussi imbriquer un package générique dans un autre comme on imbrique une macro dans une autre.

    C'est une forme très simple de générique, destinée par exemple à écrire des routines de tri, d'arbres binaires qui ont des noeuds qui portent des données, bref, plutôt des algorithmes qui resteront dans une librarie.

    Après avoir étudié l'utilisation pratique des génériques par 99% des programmeurs, je n'ai créé qu'un seul genre de type générique, privé, qui permet les assignations uniquement, c'est beaucoup plus simple que dans les autres langages, mais aussi plus compréhensible.

    Il y a un exemple de générique pour bubble-sort au chapitre 9. Generics (le manuel de référence est le lien tout en bas sur la page de début du site).

    //----------------------------------------------------------------------------

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Marc.Samuro
    R: il ne faut pas confondre le langage et le compilateur. Bon ici j'ai écris un compilateur pour windows, j'ai essayé d'optimiser au mieux le code généré mais je suis persuadé qu'il y a des spécialistes qui font cela encore mieux que moi.

    D'autres personnes peuvent tout à fait écrire leur compilateur, j'ai rédigé des spécifications techniques très précises qui décrivent le langage en détails afin que les programmes soient tous portables (voir le lien tout en bas sur la page de début du site).
    Certes cela ne relève pas du langage et reste du domaine de la qualité d'implémentation.

    Mais d'une part si la seule implémentation dudit langage souffre de souci de performance, cela ne va pas forcément aider à faire adopter ce langage.
    D'autre part, rejeter une autre langage en prétextant de mauvaises performances pour au final ne pas proposer certaines optimisations que lui fait, c'est assez ... surprenant.

    Quant à l'argument de ne pas utiliser des instructions qui ne pourraient n'être pas présente, c'est effectivement très louable comme objectif. Mais il reste possible de le proposer en option du compilateur.

    Citation Envoyé par Marc.Samuro Voir le message
    Q: Et concernant les accès hors borne du tableau ? Également à l'exécution ?
    Pourquoi ne pas chercher à vérifier ce qui peut l'être à la compilation ?

    R: le compilateur vérifie les indices de tableau (et aussi de slices de tableau, =tranches) à la compilation si les indices sont des expressions constantes.
    OK donc si je comprends bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void main()
    {
      int tab[6];
     
      tab[6] = 0;
    }
    va lever une erreur à la compilation.

    Par contre si je suis les exemples donnés, le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void main()
    {
      int tab[6];
      int i;
     
      i = 6;
      tab[i] = 0;
    }
    ne donnera qu'une erreur à l'exécution (alors qu'elle est vérifiable à la compilation).

    J'admets que ça peut relever davantage du domaine de la qualité d'implémentation que de la définition stricte du langage, mais c'est dommage.

    Citation Envoyé par Marc.Samuro Voir le message
    R: je précise mon idée : en fait dans les langages OO, quand vous créez une grande variable (classe ou tableau), vous la créez sur le heap. En C (et Safe-C) vous pouvez créer une grande variable structure ou tableau sur la pile, ce qui ne nécessite aucune indirection de pointeur pour y accéder (c'est mov eax,[ebp]offset pour charger un champ d'une struct déclarée comme variable locale) alors qu'en OO vous avez toujours un pointeur sur chaque classe (même si ça ne s'appelle pas pointeur). Il y a donc beaucoup plus de "pointeurs" (ou indirections) en langage OO qu'en C.

    Disons pour parler clairement, les langages OO créent une multitute d'objets sur le heap (pour chaque classe), le C et Safe-C n'en font que si on utilise explicitement des pointeurs.
    C'est peut être vrai pour certains langages, mais il ne faut pas généraliser.

    Typiquement en C++, on peut tout à fait créer des classes sur la pile.

    Citation Envoyé par Marc.Samuro Voir le message
    Je précise que les pointeurs ne sont pas "managés", les objets ne bougent pas, il n'y pas de garbage collection et il faut faire ses free soi-même (il y un opérateur "new" très riche pour créer même des struct et tableau dynamiques, et une commande free).
    Managé n'est peut être le bon terme (c'est vrai qu'il a une connotation très "garbage collecté"). Parlons de safe-pointeur si tu préfères.

    Citation Envoyé par Marc.Samuro Voir le message
    R: il faut recopier la chaine et ajouter un zéro, pareil qu'en C#, pour tous les APIs qui ont besoin d'un PSTR. J'ai constaté qu'il n'y en a pas tant que cela en pratique dans l'API windows, et aucun pour des fonctions qui doivent être performantes comme read & write.
    Donc à l'appelant de le gérer.

    Citation Envoyé par Marc.Samuro Voir le message
    R: oui mais elle ne sont pas passées comme en C. Les addresses et tailles des arguments variables sont tous rassemblés et mis dans un tableau et l'adresse du tableau est passé comme 1 paramètre. Je pense que le C# fait comme cela aussi. L'utilisateur peut donc créer sans problème des fonctions à nombre de paramètres variables comme printf, fprintf, etc .. avec sécurité totale.
    Je parlais d'appeler des fonctions variadic exposées par une DLL en C.

    Citation Envoyé par Marc.Samuro Voir le message
    R: un type opaque est défini comme ceci dans le .h :

    struct MON_TYPE;

    Dans le .c correspondant, il doit y avoir la déclaration complète :

    struct MON_TYPE;
    {
    int a, b, c;
    }

    Donc évidemment si un autre fichier "importe" le .h il n'a pas accès aux champs.
    C'est qui se fait en C.

    Citation Envoyé par Marc.Samuro Voir le message
    Je signale qu'il n'y a pas "d'#include" comme en C, c'est plus un import de libraries comme en C#, ce qui a pas mal d'avantages : l'ordre des imports n'a pas d'importance, il ne faut pas inclure une librairie avant une autre.
    En C non plus l'ordre des header n'a pas d'importance sauf si le header a été écrit avec les pieds.
    Mais je pense comprendre ce que tu cherches à dire.

    Citation Envoyé par Marc.Samuro Voir le message
    A signaler aussi : le compilateur 'trouve' automatiquement les fichiers à inclure. Si vous faites :

    // main.c

    use sys/mylib;


    Il va chercher un fichier mylib.h dans le répertoire ./sys et le compiler, ensuite il va voir s'il n'y a pas un mylib.c correspondant dans le même répertoire. Bref, plus la peine d'écrire des makefile, le compilateur trouve les fichiers tout seul en suivant les "use" dans chaque fichier.
    Si les dépendances et la compilation incrémentale sont gérées, c'est intéressant (au passage c'est ce que font les compilateurs JIT).

    Note toutefois que l'utilisation d'un mécanisme type make, ant ou autre permettant d'effectuer d'autres tâches que la simple compilation lors d'une génération (génération de la doc, paquetage, archivage, déploiement, etc.)

    Citation Envoyé par Marc.Samuro Voir le message
    En gros : un générique consiste à écrire un morceau de code en "paramétrant" un ou plusieurs "type" que vous ne spécifiez pas. Le compilateur va compiler ce générique en le vérifiant syntaxiquement, mais il ne va pas en générer de code assembleur.

    Une fois écrit, vous pouvez "instancier" ce package en spécifiant des types à la place des paramètres. Lors d'une commande d'instantiation le compilateur va prendre une copie du package générique, remplacer les types paramètres par vos types et générer du code. Tout cela se passe à la compilation. ça ressemble à une macro en C sauf que le package générique est vérifié syntaxiquement. On peut aussi imbriquer un package générique dans un autre comme on imbrique une macro dans une autre.
    OK, je vois.

  10. #10
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    R: il ne faut pas confondre le langage et le compilateur. Bon ici j'ai écris un compilateur pour windows, j'ai essayé d'optimiser au mieux le code généré mais je suis persuadé qu'il y a des spécialistes qui font cela encore mieux que moi.
    C'était le sens de ma question. Écrire un backend demande du travail (qui doit être en partie refait pour chaque archi), pourquoi n'avez-vous pas cherché à en réutiliser un existant ? Vous l'avez compris, c'est une question sur l'implémentation et non le langage. Si vous ne faites pas au moins les optimisations sur les tail calls, la propagation des constantes, l'inlining et une bonne allocation des registres (de type coloriage de graphe), je prédis des résultats plus lents que ceux obtenus par C#. Ce serait le comble, puisque vous sacrifiez grand nombre de fonctionnalités au nom des performances.

    (cf. les passes de LLVM et l'article Wikipedia sur les optimisations)
    Je suis persuadé qu'utiliser LLVM (ou autre) améliorerait beaucoup de choses.

    Je ne vais pas répondre à tous les points, mais je dirai juste que je ne suis pas convaincu par Safe-C. Si on écrit du C++ proprement, en évitant l'arithmétique des pointeurs et en utilisant la STL, on obtient quelque chose d'assez sûr (autant que Safe-C) tout en restant très rapide. Si on est prêt à sacrifier 5% de la vitesse, il y a le D. Si on accepte de perdre un peu plus de vitesse, mais pas tant que ça, il y a alors énormément d'alternatives bien sûres et plus haut-niveau (qui incluent un GC).

  11. #11
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    Q: Écrire un backend demande du travail (qui doit être en partie refait pour chaque archi), pourquoi n'avez-vous pas cherché à en réutiliser un existant ?

    R: et bien tout bêtement parce que je ne le connaissait pas .. le seul back-end que j'ai regardé c'est celui de microsoft qui utilise du MSIL je crois, mais ça m'a paru tellement compliqué que j'ai laissé tomber et j'ai préféré refaire quelque chose que je maitrise complètement. Au moins la doc d'Intel et AMD est claire.

  12. #12
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    Dans mon environnement professionnel, je constate que tout le monde passe au Java ou bien C#, c'est pratiquement inévitable, malgré ces bibliothèques horriblement compliquées où on passe son temps à chercher la bonne classe puis la bonne fonction et qui sont de plus en plus abstraites.

    Et si on proposait de revenir à quelque chose de simple, un langage à taille humaine, donc faire un projet en C, on vous regarderait de travers en disant : "vous imaginez 10 programmeurs en train d'écrire un programme multithread de 30,000 lignes ? à la moindre faute de pointeur vous auriez des plantages non-reproductibles que seriez incapable de diagnostiquer et corriger et cela nous couterait trop cher." Je crois que c'est pour ça j'ai commencé le Safe-C, pour proposer une alternative.

  13. #13
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Je crois que c'est pour ça j'ai commencé le Safe-C, pour proposer une alternative.
    Si je comprends bien, vous voyez votre langage en concurrence de C# et Java. C'est étonnant. À moins d'avoir des contraintes particulièrement fortes (système temps-réel, embarqué, drivers...), l'utilisation du C n'a pas beaucoup de sens.

    Citation Envoyé par Marc.Samuro Voir le message
    le seul back-end que j'ai regardé c'est celui de microsoft qui utilise du MSIL je crois, mais ça m'a paru tellement compliqué que j'ai laissé tomber
    Heureusement ! MSIL est l'assembleur de .NET, c'est-à-dire que vous auriez eu toutes ces choses que vous semblez détester : garbage collector, VM, JIT, objets...

    je constate que tout le monde passe au Java ou bien C#
    Il y a peut-être d'autres raisons que le seul fait de reproduire des bugs ?

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Beaucoup d'arguments de part et d'autres. Toutefois, il y a une chose essentielle qui n'a pas été dite (ou alors que j'ai ratée), c'est que si le C est aussi rapide et aussi léger, c'est justement parce qu'il ne vérifie rien de façon totalement volontaire. Sa philosophie est "le programmeur sait ce qu'il fait". Evidemment si le programmeur fait du C sans savoir ce qu'il fait... ou sans être capable de se gérer lui-même ses pointeurs et ses indices de tableaux, alors le C n'est pas fait pour lui.
    Donc un langage volontairement sans aucun garde-fou mais en retour on a une vitesse inégalée et une taille minime qui permet même d'embarquer des codes C sur des micro contrôleurs robots.

    De plus, pour celui qui préfère être protégé, il existe tout un tas d'autres langages moins rapides mais avec plus de protections et qui vont même jusqu'à intégrer l'objet et la gestion automatique de la mémoire (Perl, Python par exemple).

    Et donc, Marc.Samuro, tu nous proposes un langage "comme le C" (c'est à dire quand-même bien chiant il faut le dire car écrire 45 lignes pour agrandir un tableau là où ça s'écrit en une ligne de Python moi même si j'aime beaucoup le C ben ça me prends quand-même la tête...) et où tu lui as enlevé son avantage principal pour le remplacer par un autre qu'on trouve déjà par ailleurs. Désolé, perso ça ne m'intéresse pas...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    oui le choix du langage dépend évidemment du type de programmes qu'on écrit, et dépend si on privilégie la vitesse ou la sécurité.

    Quand je programme pour moi je recherche plutôt la vitesse donc ce n'est pas étonnant que je suis programmeur C depuis + de 10 ans; le problème que j'ai avec cela depuis quelque temps c'est qu'il m'est déjà arrivé de passer plusieurs jours dans le debugger en train de chercher comment diable une variable pouvait avoir reçu une valeur que normalement elle ne devrait pas,
    et finalement sans trouver la réponse. Les programmes qu'on distribue sur internet ce sont les pires à corriger parce qu'on reçoit un rapport d'erreur et on essaye tant bien que mal de reproduire le problème sur son PC.

    On finit par douter de tout, on finit par suspecter les DLL, ou on se demande si ce n'est pas à cause d'un programme que tel utilisateur a encore installé sur son PC (par ex des antivirus buggés peuvent causer des problèmes en se chargeant comme DLL, on désinstalle l'antirirus et le problème disparait).

    Chez Microsoft ils recoivent des rapports d'erreur sur des plantages de windows que des équipes sont chargées d'analyser, ce n'est pas triste non plus. J'ai eu l'occasion de lire des articles qui expliquaient que parfois
    ils trouvent encore des bugs assez énormes que personne n'a vu.

    Je vois aussi autour de moi des programmes buggés (acrobat reader qui a des dépassement de pile à plein d'endroits, le viewer second life qui crashe 5 fois par heure, etc ..).

    Tout cela ce sont des programmes écrits sans sécurité afin d'avoir une vitesse maximale, mais cette vitesse a un prix : c'est une qualité de logiciel moindre, bref des plantages, et un coût très élevé pour les corriger.

    Je suis toujours pour la vitesse, mais maintenant je veux un très mince filet de sécurité à 100% pour ne plus avoir des maux de tête dans le débugger. De la sécurité aussi légère que possible pour ne pas ralentir les programmes.
    Par exemple 2 instructions assembleur en plus pour vérifier chaque indice de tableau ne me gênent pas trop, on ne peut pas parler d'un ralentissement gênant.

    Il y a des langages qui vont au-delà de la sécurité et qui proposent des fonctions plus agréables à utiliser pour le programmeur (typiquement tous les langages avec garbage collection), mais ça a un impact beaucoup plus important sur la vitesse. Je vois régulièrement au boulot des applications C# ou Java franchement lentes ou avec des temps de réponse bien inférieurs
    à ce qu'on peux faire réaliser en C, je trouve cela navrant que les jeunes programmeurs ne savent plus créer du code rapide.

  16. #16
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    mais la technologie va peut-être tout changer : je souriais dernièrement en relisant le livre de C de Kernigan et Richie : à un moment ils proposent 2 versions d'un programme, l'une avec tableau et l'autre avec pointeurs, et ils conseillaient la version avec pointeur beaucoup plus rapide disaient-ils, par ce que sur leur processeur (PDP11 je crois), la multiplication des indices par la taille des éléments pour calculer l'offset du tableau était horriblement lente.

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Marc.Samuro Voir le message
    mais la technologie va peut-être tout changer : je souriais dernièrement en relisant le livre de C de Kernigan et Richie : à un moment ils proposent 2 versions d'un programme, l'une avec tableau et l'autre avec pointeurs, et ils conseillaient la version avec pointeur beaucoup plus rapide disaient-ils, par ce que sur leur processeur (PDP11 je crois), la multiplication des indices par la taille des éléments pour calculer l'offset du tableau était horriblement lente.
    Les pointeurs peuvent améliorer les performances dans le cas où on accède un grands nombres de fois aux éléments d'un tableau. Passer par l'indice implique qu'à chaque accès, le proc se place au début du tableau et décale ensuite de l'indice * taille élément.
    Alors qu'avec un pointeur déjà positionné sur le bon élément, toute cette opération saute. Et ça, c'est autant valable aujourd'hui qu'il y a 40 ans.

    Toutefois, ce qu'on a aujourd'hui c'est des compilos de plus en plus intelligents qui sont capables de détecter les trucs de ce genre et faire eux-même le remplacement...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #18
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Marc.Samuro Voir le message
    je souriais dernièrement en relisant le livre de C de Kernigan et Richie : à un moment ils proposent 2 versions d'un programme, l'une avec tableau et l'autre avec pointeurs, et ils conseillaient la version avec pointeur beaucoup plus rapide disaient-ils, par ce que sur leur processeur (PDP11 je crois), la multiplication des indices par la taille des éléments pour calculer l'offset du tableau était horriblement lente.

    ne souris pas trop

    C'est effectivement une optimisation courante dans de gros programmes : par exemple les programmes de biochimie et de recherche dans le domaine de la génétique, mais aussi dans énormément de calculs scientifiques, traitements de grosses images satellites ou médicales, etc etc...

    Et on voit bien que tu n'as pas trop l'expérience de ça, car les gains peuvent être faramineux : j'ai eu le cas il y a juste 4 ans d'un gain de environ 1200 %, c'est à dire passer de 18h de calcul à 20 minutes juste par le fait de remplacer des indices de tableau à l'intérieur de boucles en adresses....

    Sans parler de l'ordre des boucles, qui a fini par amener à 5 minutes de calcul le même programme...

    Mais faire 200 millions de fois des séries (1 addition et 1 multiplicatio) (pour un seul indice), ça coûte.. Et quand il y a par exemple 3 ou 4 indices dans le tableau, c'est "hors de prix" par rapport au fait de se référer aux adresses...




    Maintenant, ton idée est certainement louable, mais un certain nombre d'arguments ont été donnés plus haut, et j'en rajouterais un.. :

    étant donné qu'un des énormes avantages des langages deuis le C est la programmation dynamque, comment ferais-tu pour "vérifier à la compliation ou au runtime" quelque chose qui soit comme :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    scanf ( "%d", &nb );
     
    buf = malloc ( nb );
    ....
    puis dans une fonction quelque pat :

    ici je prend scanf, mais dans l'écrasante majorité des cas ce serait un sscanf après avoir lu la ligne dans un fichier...


    Comme le dit Sv@r, le C a volontarement laissé de côté les vérifications, et est fait pour des gens qui savent ce qu'ils font.. Et quand ils ne savent pas, ou bien ils apprennent, ou ça les dégoute et ils vont vers un langage plus encadré...


    Moi après 23 ans de programmation C, le C me convient parfaitement avec sa souplesse....



    PS: c'est pas bien de faire du spam/multiposting sur le forum, et de détourner des débats (dans la partie General Développements)....
    "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

  19. #19
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 31
    Points : 0
    Points
    0
    Par défaut
    Q: comment ferais-tu pour "vérifier à la compliation ou au runtime"
    En safe-C, il y a 3 types d'objets qu'on peut réserver sur le heap :

    a - les objets de taille constante (types simples, struct ou tableaux de longueur constante)

    exemple:
    donc là, pas de problème, un pointeur vers T sera toujours un pointeur vers T.


    b - les objets tableau dynamique

    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      float[]^ p = new float[n];
    si 'float' occupe 4 bytes, p pointe sur une zone de 4 + n*4 bytes car il y a un header de 4 bytes au début de l'objet heap qui contient la longueur du tableau. p ne pourra pointer que sur des tableaux dynamiques de float;
    donc si on fait : p^[n] = 1.2; // n est vérifié grâce au header de p

    Faisons un petit exercice académique : si j'ai envie d'agrandir le tableau, disons de le rendre 2 x plus grand :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      float[]^ q;
     
      q = new float[n*2];    // allouer header de 4 bytes + (2*n) éléments
     
      q^[0:n] = p^;    // recopier les n premiers éléments  (tranche commençant à l'indice 0, de n éléments)
      q^[n:n] = {all=> 0.0};   // le reste à zéro (tranche commençant à l'indice n, de n éléments)
     
      free p;   // libérer l'ancien tableau
      p = q;   // maintenant p pointe vers le grand tableau
    Si je veux connaitre la longueur d'un tableau j'utilise l'attribut 'length :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       longueur = p^'length;   // va chercher la longueur dans le header de l'objet pointé par p
    c- les structs avec variantes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      struct S (FIG f)
      {
        int x, y;
        switch (f)
        {
          case RECT:
            int long, larg;
          case CERCLE:
            int rayon;
        }
      }
     
      S^ p = new S (c);   // avec c runtime
    ici p ne peut pointer que sur une struct S.
    On réserve un objet heap ayant un header de 4 bytes qui contenant le discriminant (ici c) + les champs de la structure. La taille totale de l'objet dépend de la valeur c à l'exécution. (il y a un tableau constant qui permet au runtime de calculer la taille de S pour chaque valeur de c)

    Si on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     p^.rayon = 2;  // vérifie que le header de p == CERCLE.
    C'est limité à ces 3 formes parce que ce sont les plus courantes. Si vous voulez quelque chose de plus inhabituel (par exemple un struct avec un tableau qui suit la struct pour ne consommer qu'une allocation au lieu de deux, par exemple pour stocker les lignes de texte d'un éditeur), il faut travailler "sans filet" avec les unsafe pointers qui sont les mêmes qu'en C.

    Tout programme a des sections qui doivent être optimisées à fond : par exemple ce n'est pas très utile de vérifier les indices de tableau lors d'une multiplication de matrices parce que les 2 boucles imbriquées sont tellement simples qu'on 'voit à l'oeil nu' qu'on ne risque pas de sortir du tableau. Pour cela, en Safe-C, on peut utiliser les unsafe pointers du C : donc les opérateurs &, * et -> habituels, ainsi que les [] sur un pointer unsafe.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       #begin unsafe
           double d = 1.2;
           double p*;
           p = &d;     // autorisé en section unsafe
          *p = 3.4;    // sans aucune vérification
       #end unsafe
    Pour avoir une idée du coût de ces vérifications, le code pour vérifier l'indice dans :
    Une fois qu'on a 'n' dans un registre (par ex: eax), et p^ dans un autre (par ex: esi), on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        cmp eax,[esi]
        jae  error                ; >= limite ?
        mov [esi+eax*4]4,cte_1.2     ; assignation
      .. la suite
     
    error:
       int 5;   // fatal error


    p.s.: si quelqu'un peut m'expliquer comment on peut formater un message sur le forum ici, j'ai toutes mes lignes collées à gauche quand je publie.

  20. #20
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    p.s.: si quelqu'un peut m'expliquer comment on peut formater un message sur le forum ici, j'ai toutes mes lignes collées à gauche quand je publie.
    Tu peux déjà utiliser les balises [CODE] (et les lignes ne seront alors plus tassées à gauche et le formatage sera conservé) et [QUOTE] comme celles que j'ai placées sur ton message.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

Discussions similaires

  1. Nouveau langage de programmation : le langage G
    Par G-FACTION dans le forum Autres langages
    Réponses: 10
    Dernier message: 19/07/2009, 19h58
  2. Nouveau langage en python
    Par bossodo dans le forum Général Python
    Réponses: 11
    Dernier message: 17/07/2009, 10h27
  3. Nouveau langage WEB
    Par Wulfgard dans le forum Autres langages pour le Web
    Réponses: 4
    Dernier message: 27/06/2009, 13h03
  4. "Rentring" : est-ce un nouveau langage ?
    Par sergi_o dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 24/11/2006, 23h35
  5. Nouveau langage : le D
    Par cheick dans le forum D
    Réponses: 4
    Dernier message: 30/05/2004, 15h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo