Aller au contenu

Compiler du C en Java ?


Messages recommandés

Bonjour à tous !

Alors la question est peut être un peu débile, mais bon...

Pourquoi est-ce qu'on ne pourrait pas compiler du C en Java pour le faire tourner sur n'importe quel OS ?

Au lieux de faire C -> Langage Machine faire C -> Java (bytecode)

J'imagine que c'est pas possible, sinon ça existerait surement déjà, mais pourquoi ce n'est pas possible alors ?

La machine virtuel java me semblait être du point de vue conception parfaitement semblable à une machine physique "normal".

L'autre raison que j'ai imaginée, c'est que l'intérêt est nul. Se "faire chier" à développer dans un langage bas niveau pour finalement passer par une machine virtuel... (Sans vouloir troller :modoreussi: )

Dans le même genre d'idée, est-ce que tout les langages serait potentiellement convertible en bytecode Java ? Par exemple si je souhaite créer un langage de programmation pour quelque chose de très spécifique, est-ce qu'il ne serait pas judicieux (et surtout possible) de passer par l'intermédiaire "Java". ça permet d'avoir un "exécuteur" qui fonctionne sur différent OS sans avoir à le gérer directement.

Enfin, peut être que je raconte n'importe quoi et que j'ai rien compris remarque...

Merci de m'éclairer sur le sujet :)

Lien vers le commentaire
Partager sur d’autres sites

hummm, t'aurais pu chercher un peu mieux...

Après quelques recherches un peu plus poussées (et surtout en anglais) je suis tombé sur ça :

http://en.wikipedia.org/wiki/C_to_Java_Vir...ecode_compilers

qui explique que les compilateurs C vers Java existe puisque c'est une architecture cible "presque" comme une autre. la Machine virtuel Java est clairement construite pour du Java, mais ça reste tout à fait possible de l'utiliser pour d'autre langages.

Il est intéressant de noter que la plupart de ces compilateurs utilisent un langage intermédiaire (LLVM ou MIPS) ou convertissent le code en code java avant de faire la compilation en Bytecode. (ex : C -> LLVM -> ByteCode).

Par contre, ça m'a pas l'aire tellement utilisé. Reste à savoir pourquoi donc... Surement une question de rapport performance/tant de dev.

Lien vers le commentaire
Partager sur d’autres sites

Tu dis que le bytecode java est semblable à l'assembleur généré par un compilateur C++, mais ce n'est pas du tout le cas si tu y réfléchis bien :censored:

- De nombreuses différences au niveau des règles du langage (héritage multiple, templates vs. génériques, accessibilité des membres, ...)

- Un gouffre au niveau de la gestion de la mémoire (pointeurs vs. garbage collector, registres, ...)

- Des librairies complètement différentes d'un coté et de l'autre (par exemple, la classe String java n'a rien à voir avec la classe String C++; comment faire le lien ?)

Bref, de nombreux obstacles qui font que les systèmes existants pour compiler du C++ en bytecode sont généralement catastrophiques en termes de performances, à cause des nombreuses pirouettes à faire pour rendre la source compatible avec la destination. Par exemple, un appel à une méthode de libjpeg prends 0.25 secondes à s'exécuter pour une compilation native, alors que le même appel prends 2.2 secondes avec une compilation sous NestedVM-Hotspot. Une perte de performance qui décourage bien souvent les personnes qui sont éventuellement intéressés par le système pour rendre leur programme compatible sur plusieurs plate-formes.

Lien vers le commentaire
Partager sur d’autres sites

Disons que ce sont deux langages qui existent depuis longtemps et très utilisés.

Ils ont chacun leurs avantages et inconvénients bien spécifiques.

Par conséquent, dans la majorité des cas, ce qui a été fait en Java avait de bonne raison de l'être et pareil pour le C.

Si tu commences une application en C aujourd'hui, c'est que tu recherches de la performance que Java ne t'apportera pas (même si les performances ont été améliorées au fur et à mesure des versions).

Idem, si tu codes ton application en Java, c'est que tu recherches le multi plateforme, ou la relative facilité à pouvoir commencer à coder avec ce langage.

Bref, convertir de l'un à l'autre n'a pas trop d'intérêt.

Lien vers le commentaire
Partager sur d’autres sites

Si tu regarde de près c'est pas très optimisé, la majorité du temps tu perd la portabilité, donc quel intéret ? ou alors à l'inverse tu perd en performance sur le C

Bref rien de bien efficace, ces solutions servent avant tout à interfacer une appli java avec une lib C quand l'équivalent Java n'existe pas.

Pour ce qui est de développer/compiler en C en portable tu peu trouver une solution en C bien plus efficace et portable avec d'autres solutions, comme par exemple utiliser un couple C/Lib portable.

Lien vers le commentaire
Partager sur d’autres sites

  • 1 mois après...

Virtual_Spirit > le principal problème vient du fait que les paradigmes sous jacents aux modèles de mémoire et aux modèles de concurrence de Java et de C/C++/Système ne sont pas compatibles à 100%...si tu as un code monothread simple, ca passera nickel, à la libération de la mémoire près...mais à mon avis dès que tu passe en multithread avec des contextes de classloading différents :dd:

Shtong > tu peux utiliser JNI, mais tu perds en portabilité :D

>>> je rejoint favien29200 pour dire que cela n'a pas trop d'intêret de s'ammuser à faire ce genre de choses :D

fabien29200 > tu peux aussi faire le bourrin comme moi à la fac et faire tourner une appli java qui rempli le même role fonctionnel qu'une appli en C...mais comme tu est en java...tu as un déficit de perf à combler...et donc tu utilise des trucs en java d'assez bas niveau en sus de réfléchir un peu plus à l'optimisation de tes algos...je me rappelle d'un programme de segmentation qui juste parceque je reconstruisait l'image différemment et plus intelligemment que ceux qui avait fait leur truc en C, je faisait chuter la complexité globale du programme...et donc la seule limite que j'avais était le nombre d'objets que je stockait dans une file à priorité aux petits oignons...le truc c'est qu'il faut réfléchir ce que beaucoup de gens ne prennent plus la peine de faire...

Après dire que Java est un langage de haut niveau est complètement faux...comparé à Scala ou aux langages fonctionnels...c'est une hérésie pure...le modèle de mémoire est complexe, le modèle de threading n'est pas des plus simples à apréhender...les ssii mettent des juniors pour coder en java parceque toutes les écoles d'ingés mettent une couche de vernis java et balance ses ingés experts java...résultat : la plupart des gens ne savent pas libérer correctement la mémoire, du coup en cas de forte charge ponctuelle sur une appli, tu te retrouve à passer un temps plus que conséquent à faire de la garbage collection d'ilots d'objets...ce qui finit forcément mal avec au choix un permgen, ou un outofmemory...sans parler des interbloquages liés au fait que la plupart des gens n'ont aucune idée de comment coder une application multithreadée proprement...

Tout ca pour dire que souvent c'est l'algo qui fait l'essentiel de la différence de performance...pas le langage...après, l'algo et l'architecture de l'application doivent s'adapter à la plateforme cible...

Lien vers le commentaire
Partager sur d’autres sites

Le seul intérêt que je verrais à faire du C => bytecode java, c'est le modèle de programmation. Si tu a un programme entièrement pensé de manière procédural, le faire en objet (avec que des classe abstraites et des méthodes statiques, ça va faire un bordel illisible.

Mais bon, est-ce si infaisable que ça que de revoir la conception de son programme en objet ? j'ai un sérieux doute, surtout quand on voit le gain de temps à développer en java après...

@Shtong : nawak, complètement nawak. en assembleur, y a pas de modèle objet qui tienne, pas de private/public, pas d'héritage ou autre. Une fois que le compilateur a produit le code machine (ou le bytecode java), il ne reste que des octets et des opérations élémentaires (arithmétiques, déréférencement, copie en registre, pile et autre).

Lien vers le commentaire
Partager sur d’autres sites

en même temps, du code C bien pensé à souvent tendance à ressembler à du code "objet" :D

Shtong > Pour les génériques vs les templates, c'est un poil plus que simplement "une règle de langage"...c'est la conception sous jacente du compilateur (et donc dans le cas de Java de la VM) qui est différente...

- les templates >> implémentation "par extension", la template est adaptée à chaque type...fondamentalement, ce n'est pas le même code qui s'exécute si tu as une liste de int ou une liste de float

- les génériques >> implémentation "par erasure", les informations de typage sont perdues à la compilation...Java n'étant pas un langage objet pur, les génériques ne peuvent donc s'appliquer qu'aux types englobants et aux objets...que tu aie une List<Integer> ou une List<Float> ou une List tout court, le code exécuté est identique.

Après, pour ce qui est de la gestion de la mémoire, elle est autrement plus difficile en Java qu'en C (sic)...en C, il est relativement facile de détecter une fuite mémoire ou ce genre de choses...et puis les développeurs C sont généralement au courant de ce qui se passe au niveau de la mémoire, alors qu'en Java, on voit régulièrement des problèmes liés à des ilots d'objet non garbagés, selon la politique de garbage collector que l'on utilise...

Enfin, pour les types "complexe" comme String, fondamentalement, en Java ou en C, une chaine de caractère est un tableau de caractères...après, il y a caractère et caractère :D

Lien vers le commentaire
Partager sur d’autres sites

Non, juste pour faire l'embêtant

en même temps, du code C bien pensé à souvent tendance à ressembler à du code "objet" :D

Oui mais le C++ (Objet ) est transformé en C: La boucle est bouclée :francais:

Enfin, pour les types "complexe" comme String, fondamentalement, en Java ou en C, une chaine de caractère est un tableau de caractères...après, il y a caractère et caractère :D

Si tu prends le type "vector" de la STL, c'est certes juste un tableau. Mais derrière c'est un poil plus intelligent.

Il alloue par chunk pour éviter de faire trop souvent des recopies.

Et après il y a l'unicode: c'est fun l'unicode.

Lien vers le commentaire
Partager sur d’autres sites

En fait, pour le vector de la STL, c'est même tellement bien fait qu'il n'y a quasiment jamais de recopie. le vector en lui-même a une politique d'allocation exponentielle (à chaque fois qu'il doit allouer, il alloue 2 fois la taille courante, histoire de se laisser de la place), mais en plus, les OS modernes et intelligents ont des politques d'allocation qui minimisent le déplacement des donner. Quand tu alloues ton vector, bien souvent une page lui est destinée, donc on peut le faire grandir d'une sacrée taille. Si jamais il déborde, on lui alloue une nouvelle page, et le mécanisme de pagination permet de faire comme si les adresses étaient continues.

Par contre pour les génériques de Java, j'aimerai aporter une précision : Les génériques ne marchent en java que grâce au polymorphisme, et justement à cause de la type erasure. Après compilation, le bytecode est le même que ce soit une ArrayList<String> ou une ArrayList<NimporteQuoi>, et la où ça coincera, c'est avec les tentatives de cast implicite ou avec un polymorphisme impossible. Bref les génériques en java, c'est juste une aide pour ne pas écrire des conneries.

Lien vers le commentaire
Partager sur d’autres sites

En fait, pour le vector de la STL, c'est même tellement bien fait qu'il n'y a quasiment jamais de recopie. le vector en lui-même a une politique d'allocation exponentielle (à chaque fois qu'il doit allouer, il alloue 2 fois la taille courante, histoire de se laisser de la place), mais en plus, les OS modernes et intelligents ont des politques d'allocation qui minimisent le déplacement des donner. Quand tu alloues ton vector, bien souvent une page lui est destinée, donc on peut le faire grandir d'une sacrée taille. Si jamais il déborde, on lui alloue une nouvelle page, et le mécanisme de pagination permet de faire comme si les adresses étaient continues.

Quand tu regarde dans le code de certains types de collections en java, tu rencontre également ce genre de polique d'allocation (et malheureusement, tu n'a pas toujours moyen de le contrôler cette "explosion"...après, dans les collections auxquelles je pense, on voit du bon gros arraycopy, qui derrière fait appel à une méthode native, sans doute issue de la STL, mais cela ne transparait pas pour l'utilisateur final.

Par contre pour les génériques de Java, j'aimerai aporter une précision : Les génériques ne marchent en java que grâce au polymorphisme, et justement à cause de la type erasure. Après compilation, le bytecode est le même que ce soit une ArrayList<String> ou une ArrayList<NimporteQuoi>, et la où ça coincera, c'est avec les tentatives de cast implicite ou avec un polymorphisme impossible. Bref les génériques en java, c'est juste une aide pour ne pas écrire des conneries.

Autre précision sur les generics...leur implémentation par erasure était un choix ***politique*** puisqu'il permet de garder une rétro-compatibilité avec l'existant :

- il n'y a pas eu de changement majeur à faire dans la JVM...il a seulement fallu modifier le compilateur

- l'existant peut continuer de tourner sur une JVM plus moderne sans difficulté majeure

Pour c'est juste un coup à prendre...franchement y'a pas grand chose à retenir pour commencer à bien utiliser les generics :

- le principe de substitution

- l'utilisation des wildcards avec super & extends --> "put & get principle"

- l'utilisation des types paramétrés

- savoir quand utiliser les wildcards et les types paramétrés

- le boxing / unboxing

- eventuellement les varargs, mais ca reste super simple

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...