Bonjour, on voit souvent sur le web des tutoriels qui expliquent comment écrire un kernel en Asm/C mais peut-on le faire en C++ ??
Version imprimable
Bonjour, on voit souvent sur le web des tutoriels qui expliquent comment écrire un kernel en Asm/C mais peut-on le faire en C++ ??
Techniquement oui, mais ce n'est pas forcément une très bonne idée. Les avantages et les inconvénients du C sont démultipliés en C++ et dans ce contexte. Tu ne peux pas t'appuyer sur les bibliothèques habituelles dont on fait grand usage en C++, et il faut être très vigilant à la mémoire et autres ressources que ton programme consomme quand on écrit un noyau. Cela t'oblige à avoir un oeil circonspect sur l'usage de toutes les facilités du C++.
Exemple : l'héritage. Si tu en fais un usage massif, tes objets peuvent vite devenir très gros, et quand tu changes ou ajoutes un membre dans une classe de base, cela a un impact sur le projet entier.
D'accord mais, si j'utilise seulement les class pour ne pas avoir de variable global ....
je suis plusieurs tutoriel sur le web et il utilise tous des variables globale pour la position du curseur de la console .... alors je voudrai créer une class Console par exemple ...
Oui je suis sure. La console n'était qu'un exemple !!!
Bonjour,
pour avoir déjà tenté l'expérience, je peux t'assurer que c'est possible. Toutefois il y a déjà quelques inconvénient par rapport au C:
- le C n'est déjà pas très standard lorsqu'il s'agit de créer un OS mais en C++ c'est bien pire, il faut implémenter quelques routines très obscures spécifiques au compilateur qu'on utiliser. Autant les recopier texto des quelques sites où on peut les trouver.
- il faut toujours avoir en tête le problème de la mémoire, notamment au début. En C, le problème ne se pose pas car tu fais un {k,m}alloc donc cela se voit mais en C++ cela peut être beaucoup plus fourbe pour peu que tu manipules des chaînes de caractères, des vecteurs, ... Prudence donc !
Par contre, on a aussi les avantages du C++ donc je pense que cela vaut le coup.
Quant à ce que dit Obsidian, je ne suis pas convaincu que la place prise en mémoire soit vraiment un problème si on n'utilise pas des classes à toutes les sauces et là où on ne devrait pas.
Enfin, je pense que l'intérêt d'utiliser le C++ juste pour avoir des classes en lieu et place des variables globale est assea faible. Dans ce cas, autant utiliser toute la puissance du C++.
On préfère l'assembleur (pour son accès total à toutes les ressources de la machine) et le C (pour ses capacités très proches de l'assembleur plus sa légèrté, son caractère "haut niveau" et sa portabilité). Le C++ est plus strict que le C sur les types (donc déjà moins proche de la machine) et trop complexe (les compilateurs C++ qui ont déjà été utilisés pour développer des systèmes sont très très loin du C++ standard. De nombreuses fonctionnalités pourtant normalisées ne sont généralement pas implémentées. On n'utilise donc pas vraiment "le langage C++" mais un sous-ensemble du langage C++) pour rivaliser avec le C pour l'écriture de noyaux. Si tu veux un exemple de système écrit en C++ : Symbian OS, le noyau des plateformes S60, S80, etc. (Nokia) et UIQ (Sony Ericsson).Citation:
Envoyé par spiner900
Ah non ! Le C standard permet très bien d'écrire un noyau. C'est seulement la bibliothèque standard qu'on ne peut plus utiliser (plus précisément, certaines fonctions de la bibliothèque standard, comme printf, malloc, etc. bref toutes les fonctions qui s'appuient sur des appels systèmes ...). Il ne faut pas confondre ce que j'ai dit avec "Tous les compilateurs C peuvent être utilisés pour compiler un noyau", tout comme on n'utilise pas un compilateur Win32 pour générer un exécutable Linux. Il faut bien sûr les outils prévus pour ... (gcc + ld par exemple).Citation:
Envoyé par amaury pouly
BeOS était écrit en C++. En fait, BeOS est la preuve qu'on peut faire un très bon système en C++ (meilleur que ses concurrents de l'époque).Citation:
Si tu veux un exemple de système écrit en C++ : Symbian OS, le noyau des plateformes S60, S80, etc. (Nokia) et UIQ (Sony Ericsson).
Hum...
À ma connaissance, il est impossible d'écrire entièrement un noyau en C ou en C++, car ces langages n'ont rien pour gérer les interruptions...
Dans tous les cas, il faut à bas niveau des fonctions écrites directement en assembleur.
Je pense aussi que les premières instruction du démarrage (installation de la pile initiale, création de la table d'interruptions initiales, ...) doivent être écrites en assembleur.
http://www.opensource.apple.com/darwinsource/
l'inscription est gratuite…
Merci pour la précision. J'ai eu que peu de cours mac, ^^.
Écrire un système d'exploitation ou un noyau en C++, en utilisant des idiomes comme le RAII, serait une très bonne chose et augmenterait la robustesse du système.
Personne n'en a encore créé, cependant.
Je ne parlais pas de la bibliothèque standard mais bien du langage. Contrairement au C, le C++ laisse énormément de marge pour l'implémentation. Il n'y a qu'à voir les routines à implémenter avec VisualC++ et G++ pour pouvoir utiliser des classes pour s'en convaincre: cela va des appels à des méthode virtuelles pures aux allocations sur la pile, en passant par les constructeurs et destructeurs statiques, new et delete bien sûr, RTTI(certes c'est peu utile dans un noyau), les exceptions(idem),...Citation:
Ah non ! Le C standard permet très bien d'écrire un noyau. C'est seulement la bibliothèque standard qu'on ne peut plus utiliser (plus précisément, certaines fonctions de la bibliothèque standard, comme printf, malloc, etc. bref toutes les fonctions qui s'appuient sur des appels systèmes ...). Il ne faut pas confondre ce que j'ai dit avec "Tous les compilateurs C peuvent être utilisés pour compiler un noyau", tout comme on n'utilise pas un compilateur Win32 pour générer un exécutable Linux. Il faut bien sûr les outils prévus pour ... (gcc + ld par exemple).
Mon commentaire est simplement là pour dire qu'avec le C++ on s'enfonce encore plus dans les arcanes des compilateurs qu'avec le C.
De plus, écrire un noyau en C standard relève de l'exploit. Quelques problèmes:
* Alignement des structures
* Assembleur "inline"(ça peut être utile)
Toutefois c'est vrai qu'une fois ces quelques désagréments passés, le reste c'est du C tout ce qu'il y a de plus standard.
Voilà. C'est bien ce que je voulais soutenir. Et je l'ai déjà d'ailleurs dit, le C utilisé pour écrire un noyau peut rester 100% standard, ce sont les outils à utiliser qu'il faut bien choisir. On ne compile pas un noyau avec n'importe quel compilateur. Il y a des outils spécialisés. J'ai déjà donné des exemples. L'assembleur en ligne n'est pas obligatoire, c'est juste une facilité qu'on aime utiliser (pariel pour la plupart des fonctionnalités non standard généralement utilisées ...). On peut très bien développer toutes les routines dont l'implémentation dépendent d'une plateforme particulière en assembleur et appeler ces routines depuis le C.Citation:
Envoyé par amaury pouly
Bien sûr. Tout n'est pas écrit entièrement en C. C'est le noyau (et tout ce qui se trouve au-dessus) qui peut être entièrement écrit en C. Généralement, avant de coder le noyau, on développe la couche d'abstraction matérielle (HAL), une interface portable écrite dans le langage du processeur pour chaque processeur. Pour les interruptions, on les gère soit par "interruption" (avec des fonctions de rappel) soit par scrutation (boucles ...). Mais tout ça, c'est implémenté par le HAL. Le noyau peut toujours être entièrement écrit en C.Citation:
Envoyé par Médinoc
Pourquoi tu voudrais utiliser des horreurs pareilles ?Citation:
Ca aurait un petit coût de mettre des pointeurs intelligents & compagnie
Les pointeurs c'est mal, et les pointeurs intelligents ne sont pas mieux...
Tu peux penser ce que tu veux des pointeurs mais dans un noyau, les pointeurs ce sont tes meilleurs amis... Il n'y a que ça ! Les pointeurs intelligents apportent une sûreté non négligeable dans un gros projet. D'ailleurs il n'y a qu'à regarder du code en C pour voir qu'on passe son temps à gérer les allocations/libération de mémoire et les erreurs. En C++, on peut faire ça plus proprement et se concentrer sur ce que fait le code.Citation:
Pourquoi tu voudrais utiliser des horreurs pareilles ?
Les pointeurs c'est mal, et les pointeurs intelligents ne sont pas mieux...
Citation:
Voilà. C'est bien ce que je voulais soutenir. Et je l'ai déjà d'ailleurs dit, le C utilisé pour écrire un noyau peut rester 100% standard, ce sont les outils à utiliser qu'il faut bien choisir. On ne compile pas un noyau avec n'importe quel compilateur. Il y a des outils spécialisés. J'ai déjà donné des exemples. L'assembleur en ligne n'est pas obligatoire, c'est juste une facilité qu'on aime utiliser (pariel pour la plupart des fonctionnalités non standard généralement utilisées ...). On peut très bien développer toutes les routines dont l'implémentation dépendent d'une plateforme particulière en assembleur et appeler ces routines depuis le C.
En général, le HAL fait partie du noyau, c'est *juste* la partie "hardware-dependent" du noyau si l'on peut le dire. Toutefois avec une telle conception du HAL, la quantité de code à écrire n'est pas du tout négligeable et une bonne partie peut être écrite en C (pas très standard pour le coup). La partie à écrire en assembleur peut quand même être réduite au minimum.Citation:
Bien sûr. Tout n'est pas écrit entièrement en C. C'est le noyau (et tout ce qui se trouve au-dessus) qui peut être entièrement écrit en C. Généralement, avant de coder le noyau, on développe la couche d'abstraction matérielle (HAL), une interface portable écrite dans le langage du processeur pour chaque processeur. Pour les interruptions, on les gère soit par "interruption" (avec des fonctions de rappel) soit par scrutation (boucles ...). Mais tout ça, c'est implémenté par le HAL. Le noyau peut toujours être entièrement écrit en C.
Je ne suis par contre pas d'accord avec toi sur le fait que les fonctionnalités listées sont des facilités des compilateurs dont on peut se passer. Pour l'assembleur en ligne je te l'accorde mais le problème de l'alignement n'est pas négligeable par exemple. Même dans le noyau on a besoin, ne serait-ce que pour communiquer avec le matériel.
Quel rapport ?
Le problème des pointeurs, c'est l'aliasing. La possibilité de référencer la même variable depuis plusieurs parties du code, ce qui rend le programme difficile à comprendre et à analyser.
Pour ces raisons, les pointeurs (ou tout objet se comportant comme eux), c'est à éviter.
Programmer avec des valeurs (éventuellement non copiables), c'est bien mieux, c'est évident. Plus sûr, plus efficace (pas de partage, localité...), déterministe... Ce n'est plus à démontrer.
Mais même un conteneur de valeurs contient des pointeurs, tu sais...
Un vector peut alors être assimilé à un pointeur intelligent sur un tableau, donc selon toi il ne devrait pas être utilisé?
En l'occurrence, certains langages fonctionnels n'ont absolument pas de pointeurs ni d'aliasing.Citation:
Mais même un conteneur de valeurs contient des pointeurs, tu sais...
Je pense notamment à coq, mais on ne fait rien de sérieux en coq. Pour oCaml (pour parler d'un langage avec lequel on fait des choses sérieuses), je ne sais pas.
En fait, il suffit d'avoir des références (certes, une référence est un pointeur déguisé) pour que le problème d'aliasing existe... Et on a besoin de références pour être efficace (copier 100000 éléments, ce n'est pas envisageable).
Le seul embryon d'approche que je vois, dans une approche oo, ce serait de n'avoir que la sémantique de move sur les références (ie la copie d'une référence invalide la référence copiée). Pas sûr que ça règle tous les problèmes, et à peu près sûr que ça en introduit d'autres...
Ben ce passait des pointeurs pourquoi pas... se passait des smart pointers j'ai plus de mal déjà là...
Enfin dans le cadre d'un noyau je ne saurais dire ..
@loufoque > dans un noyau, un truc très bas niveau, tu manipules des adresses, tu intéropères avec l'assembleur, tu ne peux pas te permettre de ne bosser que par copie.
Un OS en Haskell ou OCaml ce serait sympa, mais bonjour pour à chaque opération avoir une nouvelle valeur pour le résultat, au lieu d'avoir modifié celle d'entrée. Après, la paresse peut jouer, mais bon pour un noyau je ne sais pas si ça serait indiqué :?
Je pense pas que loufoque voulait dire copier à tout va. Le copy on write, ça fait de la sémantique de valeur sans copie redondante par exemple.
Pour Haskell et OCaml, il faudrait se demander dans quelle mesure leurs avantages de langage fonctionnel et de typage fort sont utiles. Le fait d'avoir une nouvelle valeur ça veut pas dire qu'en interne il n'y ait pas eu modification :).
Le copy-on-write, c'est uniquement utile si tu copies beaucoup ta valeur sans en avoir réellement besoin.
La meilleure solution, c'est que si bien entendu tu n'as pas besoin de copier ta valeur, de ne pas la copier.
Les sémantiques de mouvement aident pas mal pour ça. Sans sémantique de mouvement, effectivement, mieux vaut opter pour du copy-on-write.
Un vecteur ça a une sémantique de valeur, pas de référence.Citation:
Mais même un conteneur de valeurs contient des pointeurs, tu sais...
Un vector peut alors être assimilé à un pointeur intelligent sur un tableau, donc selon toi il ne devrait pas être utilisé?
Que ça utilise des pointeurs on s'en fout.
T a;
T b = a;
a.mutate(); // avec une opération de mutation à définir, qui dépend de ce que symbolise la valeur T
=> b non modifié, sémantique valeur
=> b modifié, sémantique référence
On remarquera que si T est immutable, ça n'a pas de sens de parler de ces sémantiques-là. Le partage comme la copie sont équivalents dans ce cas.
Tout ce qui se comporte comme un pointeur ou une réference, oui.
hum.... comment peut-on écrire du C orienté objet ??? avec des structure et des pointeur de fonctions ??
Ques tu veux dire Loufoque par ''idiomes comme le RAII'' ??
et quesce que vous voulez dire par pointeur intelligent ??