Accueil Ti-Gen Foire Aux Questions Chat sur le chan #tigcc sur IRC
Liste des membres Rechercher Aide
Bienvenue Invité !   Se connecter             Mes sujets   
Administrer
0 membre(s) et 1 visiteur(s) actif(s) durant les 5 dernières minutes Utilisateurs actifs : Aucun membre + 1 visiteur
Avant de poster sur le forum, il y a des régles de bases à respecter pour une bonne entente et un respect de tous.
Veuillez lire la charte du forum.
  :: Index » Forum Ti68K » Programmation C » Orienté objet avec TIGCC (113 réponse(s))
./REPRISE DU POST PRECEDENT (post n°38)   Marquer comme non lu.
Kevin Kofler Ecrit le: Mercredi 18 octobre 2006 à 15:45 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


Quésoft :
Je disais que l'OO gardait son avantage même dans la situation décrite par Kevin: dans une telle situation je devrai implémenter une fonction pour tous mes types de donnée abstraits en C

Mais une seule (avec un switch dedans).

ou si je n'ai pas à le faire parce qu'un traitement générique existe, en OO c'est pas plus fastidieux: je n'ai qu'à ajouter une méthode à la superclasse, qui sera héritée.

Et avec les switches, l'équivalent est le cas default. (Et bien sûr, si c'est le seul cas, on peut se passer complètement du switch.)

C'est comme dans l'autre cas, avec l'OO, tu rajoutes un seul objet, mais tu es quand-même obligé de coder toutes ses méthodes qui diffèrent de l'implémentation générique. Avec le procédural, on rajoute ça aux fonctions existantes (et il peut aussi y avoir une implémentation générique, le cas default).

La différence entre les 2 paradigmes, c'est le regroupement, le code à écrire en fin des comptes est le même.

Pour la syntaxe C++, je disais que selon mes souvenir, cela se gâtait rapidement. Si mes souvenir sont bons, pour passser des paramètres à un objet alloué localement, c'est quelque chose du genre : maclasse monobjet(mesparametres) ?

Oui.
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°39   Marquer comme non lu.
Kevin Kofler Ecrit le: Mercredi 18 octobre 2006 à 15:50 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


D'ailleurs, la structure procédurale est possible même dans certains systèmes OO:
void f(Object *o)
{
  switch (o->clsid()) {
    case CLSID_FOO:
      ...
      break;
    case CLSID_BAR:
      ...
      break;
    case CLSID_BAZ:
      ...
      break;
    default:
      throw(AbstractMethodException);
  }
}

(mais bien sûr on se fait taper dessus si on pond ça :D).

(D'ailleurs, KTIGCC fait ça à plein d'endroits avec QListViewItem::rtti(). ;))
-Edité le Mercredi 18 octobre 2006 à 15:53 par Kevin Kofler-
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°40   Marquer comme non lu.
geogeo Ecrit le: Mercredi 18 octobre 2006 à 20:26 Déconnecté(e)    Voir le profil de geogeo Envoyer un email à geogeo Visiter le site WEB de geogeo Envoyer un message privé à geogeo  


Kevin Kofler:
(D'ailleurs, KTIGCC fait ça à plein d'endroits avec QListViewItem::rtti(). ;))


beurk. :D
Webmaster du site.
Programmeur sur TI68K. Arkanoid, Nebulus, GFA-Basic.

Plus d'informations sur GFA-Basic (un langage Basic pour TI68K).
http://www.tigen.org/gfabasic
    
./Post n°41   Marquer comme non lu.
Onur Ecrit le: Mercredi 18 octobre 2006 à 20:28 Déconnecté(e)    Voir le profil de Onur Envoyer un email à Onur Visiter le site WEB de Onur Envoyer un message privé à Onur  


En tout cas, si tu le fais, ca va etre trop bien :)
Je ne veux pas faire quelque chose de bien, je cherche l'excellence:ETP Studio...


et autres projets à finir avant 2010
    
./Post n°42   Marquer comme non lu.
Sasume Ecrit le: Mercredi 18 octobre 2006 à 23:02 Déconnecté(e)    Voir le profil de Sasume Envoyer un email à Sasume Visiter le site WEB de Sasume Envoyer un message privé à Sasume  

C'est vrai que le C++ génère des exécutables plus lourds qu'en C :(
Mais en même temps, c'est très agréable d'avoir à sa disposition des possibilité d'OO intégrées au langage qui permettent de simplifier l'écriture du code.
Je pense qu'un compilateur C++ -> C est une mauvaise idée : ça me semble difficile de produire des exécutables légers en empilant les couches les unes au-dessus des autres. En même temps je n'ai pas d'expérience en écriture de compilateurs, donc peut-être que je dis n'importe quoi (Pollux ? :D)
    
./Post n°43   Marquer comme non lu.
Sasume Ecrit le: Mercredi 18 octobre 2006 à 23:22 Déconnecté(e)    Voir le profil de Sasume Envoyer un email à Sasume Visiter le site WEB de Sasume Envoyer un message privé à Sasume  

Ce qui me semble utile, personnellement, c'est surtout le polymorphisme.
Je pense que du typage statique suffit (c'est plus propre déjà, et puis ça simplifie les choses).
La gestion automatique de la mémoire serait vraiment pratique également. Je ne sais pas si un GC serait très judicieux si on suppose que le programme reste mono-thread. Peut-être est-il possible de faire un système de comptage de référence ? (je n'ai pas trop réfléchi là-dessus...)
La surchage peut-être intéressante aussi, même si ça ne me semble pas le point le plus important. Je pense que ça doit être un peu lourd à gérer à travers les bibliothèques partagées.
-Edité le Mercredi 18 octobre 2006 à 23:28 par Sasume-
    
./Post n°44   Marquer comme non lu.
Quésoft Ecrit le: Mercredi 18 octobre 2006 à 23:34 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Kevin Kofler :
Mais une seule (avec un switch dedans).


C'est vrai qu'en OO il y en a plusieurs, mais en terme de code, c'est comparable (nouveaux case, vs nouvelles déclaration de méthodes).

Kevin Kofler :
Et avec les switches, l'équivalent est le cas default. (Et bien sûr, si c'est le seul cas, on peut se passer complètement du switch.)

C'est comme dans l'autre cas, avec l'OO, tu rajoutes un seul objet, mais tu es quand-même obligé de coder toutes ses méthodes qui diffèrent de l'implémentation générique. Avec le procédural, on rajoute ça aux fonctions existantes (et il peut aussi y avoir une implémentation générique, le cas default).


C'est ce que je dis: ça reviens un peu au même en terme de code dans ce cas précis. C'est juste plus clean en OO, selon moi.

La différence entre les 2 paradigmes, c'est le regroupement, le code à écrire en fin des comptes est le même.

Kevin Kofler :
Oui.

Il y a pire, et à moins de trouver mieux c'est sur quoi je vais tabler, mais je trouve que la manipulation d'objets locaux est très laide en C++.
    
./Post n°45   Marquer comme non lu.
Quésoft Ecrit le: Mercredi 18 octobre 2006 à 23:35 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Kevin Kofler :
D'ailleurs, la structure procédurale est possible même dans certains systèmes OO:


L'expressivité d'un langage OO étant suppérieure à un langage procédural, c'est normal que l'on puisse faire du procédural dans un langage OO.

Par contre, on voit que ce n'est pas particulièrement cute.
    
./Post n°46   Marquer comme non lu.
Quésoft Ecrit le: Mercredi 18 octobre 2006 à 23:40 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Sasume :
Ce qui me semble utile, personnellement, c'est surtout le polymorphisme.
Je pense que du typage statique suffit (c'est plus propre déjà, et puis ça simplifie les choses).
La gestion automatique de la mémoire serait vraiment pratique également. Je ne sais pas si un GC serait très judicieux si on suppose que le programme reste mono-thread. Peut-être est-il possible de faire un système de comptage de référence ? (je n'ai pas trop réfléchi là-dessus...)
La surchage peut-être intéressante aussi, même si ça ne me semble pas le point le plus important. Je pense que ça doit être un peu lourd à gérer à travers les bibliothèques partagées.
-Edité le Mercredi 18 octobre 2006 à 23:28 par Sasume-


Pour moi, l'OO repose essentielement sur le polymorphisme (le vrai, on s'entend, pas le sucre syntaxique qu'est le polymorphisme syntaxique ou celui des opérateurs), avant même l'encapsulation et l'héritage. Bien sûr ces trois concept sont étroitement intereliés...

Le problème d'un GC est que c'est complexe (il faut oublier un préprocesseur pour faire qqc d'efficace) et cela amène inévitablement un overhead (probablement acceptable pour une application sur PC, déjà moins pour un utilitaire système et probablement inacceptable sur TI).
    
./Post n°47   Marquer comme non lu.
Quésoft Ecrit le: Mercredi 18 octobre 2006 à 23:41 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Onur :
En tout cas, si tu le fais, ca va etre trop bien :)


J'ai le tokenizer de fait, reste le parser, plus le modèle OO, puis la conversion, etc.
    
./Post n°48   Marquer comme non lu.
Kevin Kofler Ecrit le: Jeudi 19 octobre 2006 à 02:06 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


Sasume :
La gestion automatique de la mémoire serait vraiment pratique également. Je ne sais pas si un GC serait très judicieux si on suppose que le programme reste mono-thread. Peut-être est-il possible de faire un système de comptage de référence ? (je n'ai pas trop réfléchi là-dessus...)

Je pense que tout ça est vraiment très mal adapté à la plateforme. Si on ne veut pas se casser la tête avec la mémoire, on alloue l'objet sur la pile et c'est tout. Ou alors on utilise un objet handle (une forme de smart pointer) (excusez le mélange de syntaxes C++ et Java, ça va faire du C#-like, je suppose ;)):
class FooHandle {
  public Foo p;
  public FooHandle() {p=new Foo();}
  virtual public ~FooHandle() {delete p;}
};

En C++, on peut rajouter du "syntaxic sugar" par dessus cette idée, genre utiliser des templates (donc pas besoin d'avoir un handle pour chaque type d'objet), et mettre un operator-> pour qu'on puisse utiliser ça comme un Foo *.

Je pense que ça doit être un peu lourd à gérer à travers les bibliothèques partagées.

On s'en fout, il n'y a pas de bibliothèques partagées en _nostub.
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°49   Marquer comme non lu.
Pollux Ecrit le: Jeudi 19 octobre 2006 à 21:25 Déconnecté(e)    Voir le profil de Pollux Envoyer un email à Pollux Envoyer un message privé à Pollux  

Quésoft :
Kevin Kofler :
Mais en général, il ne pourra pas. Les méthodes virtuelles ne servant que quand on a besoin d'une forme particulière de polymorphisme, ce n'est pas normal que ce soit le comportement par défaut et que c'est au préprocesseur ou frontend de prouver que ce n'est pas nécessaire dans ce cas particulier.

Je ne suis pas sûr que la majorité des cas ne pourront pas être aisément optimisés. D'expérience, les instances sont le plus souvent 'précisément typés' et cela fait que l'on peut aisément identifier les méthodes à invoquer.

C'est pas parce que tu as un type "précis" que tu connais pour autant la méthode à invoquer -- à moins que la classe soit "final", ou à moins d'être dans un cas gentil où l'appel de la méthode se trouve juste après la construction de l'objet ^^

Des objets gérés automatiquement (comme en C) est effectivement quelque chose d'utile - en particulier lorsque l'on songe à de telles optimisations. Reste à trouver une syntaxe élégante. Aussi, déterminer quand 'finaliser' un objet peut causer des tracas (e.g. appel d'une fonction au millieu de la méthode qui contient un exit() - statiquement, il y a plein de cas comme celui-ci à penser).

C'est tout le problème de la gestion des exceptions en C++ : et tu vas énormément galérer pour faire qqch d'efficace en taille si le compilo C derrière ton préprocesseur n'a pas, lui aussi, une espèce de support des exceptions...


Mais tout ça c'est secondaire, comme je l'ai déjà dit dans un sujet de ce style, ce qui est vraiment important là-dedans, c'est comment tu vas gérer la mémoire : est-ce que chaque création de chaîne va passer plus de 20000 cycles à appeler malloc() ? (c'est vraiment un chiffre énorme : ça veut dire qu'un jeu à 30 fps ne peut pas créer plus de 15 objets par frame -- rien qu'une ligne innocente du style Display("score: "+score+" (high="+highscore+")") utiliserait déjà 66% de tout le cpu... [il faut 2 allocations par chaîne, une pour stocker l'objet String, et une pour stocker le contenu de la chaîne])
A mon avis si tu veux que ça puisse être utilisable sans être affreusement lent il faut que tu implémentes tes propres routines d'allocation de mémoire -- et c'est qqch de nettement plus important que d'écouter Kevin qui va faire une crise pour gagner 3 cycles sur les appels de fonctions virtuelles ^^


Sasume :
C'est vrai que le C++ génère des exécutables plus lourds qu'en C :(
Mais en même temps, c'est très agréable d'avoir à sa disposition des possibilité d'OO intégrées au langage qui permettent de simplifier l'écriture du code.
Je pense qu'un compilateur C++ -> C est une mauvaise idée : ça me semble difficile de produire des exécutables légers en empilant les couches les unes au-dessus des autres. En même temps je n'ai pas d'expérience en écriture de compilateurs, donc peut-être que je dis n'importe quoi (Pollux ? :D)

Je pense pas que ça soit vraiment un pb, en tout cas si le compilateur C++ -> C est "intelligent" et ne se limite pas à un préprocesseur quasi-textuel : tu parles de légèreté, par exemple le compilo C++ -> C peut parfaitement être capable de déterminer quelles sont les fonctions virtuelles qui sont vraiment nécessaires au programme, s'il connaît l'intégralité du programme :) (c'est nettement plus délicat en compilation séparée, mais sur TI la compilation séparée n'est pas nécessaire)

Par contre c'est vrai qu'il faut sûrement un peu plus que le C standard : si on veut un GC ou une gestion des exceptions, il faut que le compilo soit capable de dire où il a stocké les objets si on veut éviter d'appeler penser_a_liberer(objet) à chaque exécution de la fonction ^^
    
./Post n°50   Marquer comme non lu.
Kevin Kofler Ecrit le: Jeudi 19 octobre 2006 à 23:54 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


Pollux :
C'est tout le problème de la gestion des exceptions en C++ : et tu vas énormément galérer pour faire qqch d'efficace en taille si le compilo C derrière ton préprocesseur n'a pas, lui aussi, une espèce de support des exceptions...

TIGCC gère les exceptions jusqu'à un certain niveau, cf. TRY etc. Le problème, c'est qu'il faut que certains trucs soient volatile pour que ça marche, par exemple ceci ne fonctionne pas:
HANDLE h=0;
TRY
  h=HeapAllocThrow(100);
FINALLY
  if (h) HeapFree(h);
ENDFINAL

alors que ceci fonctionne:
volatile HANDLE h=0;
TRY
  h=HeapAllocThrow(100);
FINALLY
  if (h) HeapFree(h);
ENDFINAL

(cf. la discussion sur TICT HQ pour toutes les subtilités qui entrent en jeu ici).

Mais tout ça c'est secondaire, comme je l'ai déjà dit dans un sujet de ce style, ce qui est vraiment important là-dedans, c'est comment tu vas gérer la mémoire : est-ce que chaque création de chaîne va passer plus de 20000 cycles à appeler malloc() ? (c'est vraiment un chiffre énorme : ça veut dire qu'un jeu à 30 fps ne peut pas créer plus de 15 objets par frame -- rien qu'une ligne innocente du style Display("score: "+score+" (high="+highscore+")") utiliserait déjà 66% de tout le cpu... [il faut 2 allocations par chaîne, une pour stocker l'objet String, et une pour stocker le contenu de la chaîne])

C'est bien pour ça qu'il faut gérer les objets sur la pile!

A mon avis si tu veux que ça puisse être utilisable sans être affreusement lent il faut que tu implémentes tes propres routines d'allocation de mémoire

... ou alors que tu évites d'allouer de la mémoire pour les objets qui sont 1. petits et 2. temporaires, la pile sert à ça. :)
Écrire ses propres fonctions d'allocation est une mauvaise idée, ça consomme des centaines d'octets.

et c'est qqch de nettement plus important que d'écouter Kevin qui va faire une crise pour gagner 3 cycles sur les appels de fonctions virtuelles ^^

Je m'en fous des 3 cycles, ce qui m'intéresse, c'est se passer de la vtable, ce qui permet au linker de ne linker que les méthodes effectivement utilisées. Si on a une vtable, on doit tout linker. C'est ce gain de taille qui m'intéresse. (Tu devrais le savoir, après tout ce temps. ;))

Je pense pas que ça soit vraiment un pb, en tout cas si le compilateur C++ -> C est "intelligent" et ne se limite pas à un préprocesseur quasi-textuel

Sauf qu'a priori, Quésoft m'a plutôt l'air parti pour le préprocesseur "quasi-textuel". :(

Par contre c'est vrai qu'il faut sûrement un peu plus que le C standard : si on veut un GC ou une gestion des exceptions, il faut que le compilo soit capable de dire où il a stocké les objets si on veut éviter d'appeler penser_a_liberer(objet) à chaque exécution de la fonction ^^

Euh, a priori il a GCC et c'est tout. Je ne vais pas m'amuser à rajouter des builtins pour ce genre de trucs dans TIGCC, s'il veut que son travail s'intègre bien à TIGCC, il doit coder un frontend GCC. De plus, il veut que son préprocesseur fonctionne avec n'importe quel compilateur C. Donc le C standard est tout ce qu'il a.
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°51   Marquer comme non lu.
Kevin Kofler Ecrit le: Jeudi 19 octobre 2006 à 23:58 Déconnecté(e)    Voir le profil de Kevin Kofler Envoyer un email à Kevin Kofler Visiter le site WEB de Kevin Kofler Envoyer un message privé à Kevin Kofler  


<HS> Au fait, pour les chaînes de caractères construites sur la pile, je vous présente concat.h:
http://www.tigen.org/kevin.kofler/ti89prog/concat.h
Avec ça, vous pouvez écrire:
C(C(C(C("score: ",score)," (high="),highscore),")")

(et score et highscore peuvent être des entiers ou même des flottants) et ça vous donne une chaîne de caractères allouée sur la pile avec alloca (donc pas de soucis pour libérer la mémoire ou autres).</HS>
Membre de l'équipe de TIGCC: http://tigcc.ticalc.org
Mainteneur du portage Linux/Unix de TIGCC: http://tigcc.ticalc.org/linux/
Membre de l'équipe de CalcForge: http://www.calcforge.org:70/

Participez à la reprise de Ti-Gen!
    
./Post n°52   Marquer comme non lu.
Quésoft Ecrit le: Vendredi 20 octobre 2006 à 01:17 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Pollux :
Quésoft :
Kevin Kofler :
Mais en général, il ne pourra pas. Les méthodes virtuelles ne servant que quand on a besoin d'une forme particulière de polymorphisme, ce n'est pas normal que ce soit le comportement par défaut et que c'est au préprocesseur ou frontend de prouver que ce n'est pas nécessaire dans ce cas particulier.

Je ne suis pas sûr que la majorité des cas ne pourront pas être aisément optimisés. D'expérience, les instances sont le plus souvent 'précisément typés' et cela fait que l'on peut aisément identifier les méthodes à invoquer.

C'est pas parce que tu as un type "précis" que tu connais pour autant la méthode à invoquer -- à moins que la classe soit "final", ou à moins d'être dans un cas gentil où l'appel de la méthode se trouve juste après la construction de l'objet ^^


Je ne parlais pas vraiment des cas où on peut évaluer statiquement la classe de l'objet parce qu'il est instancié à l'intérieur de la méthode. Souvent, les méthodes invoquées en sont pas overidée par les sous classes de la classe typée pour l'objet. Lorsque ce n'est pas le cas, c'est généralement parce que l'algorithme repose sur le polymorphisme, donc rien à optimiser.

Pollux :
Des objets gérés automatiquement (comme en C) est effectivement quelque chose d'utile - en particulier lorsque l'on songe à de telles optimisations. Reste à trouver une syntaxe élégante. Aussi, déterminer quand 'finaliser' un objet peut causer des tracas (e.g. appel d'une fonction au millieu de la méthode qui contient un exit() - statiquement, il y a plein de cas comme celui-ci à penser).

C'est tout le problème de la gestion des exceptions en C++ : et tu vas énormément galérer pour faire qqch d'efficace en taille si le compilo C derrière ton préprocesseur n'a pas, lui aussi, une espèce de support des exceptions...

Moka gérait les exception de façon similaire à Java en utilisant les méchanismes de TIGCC. Pour ce nouveau préprocesseur, je ne pense pas que ce sera implémenté dans un premier temps.

Pollux :
Mais tout ça c'est secondaire, comme je l'ai déjà dit dans un sujet de ce style, ce qui est vraiment important là-dedans, c'est comment tu vas gérer la mémoire : est-ce que chaque création de chaîne va passer plus de 20000 cycles à appeler malloc() ? (c'est vraiment un chiffre énorme : ça veut dire qu'un jeu à 30 fps ne peut pas créer plus de 15 objets par frame -- rien qu'une ligne innocente du style Display("score: "+score+" (high="+highscore+")") utiliserait déjà 66% de tout le cpu... [il faut 2 allocations par chaîne, une pour stocker l'objet String, et une pour stocker le contenu de la chaîne])
A mon avis si tu veux que ça puisse être utilisable sans être affreusement lent il faut que tu implémentes tes propres routines d'allocation de mémoire -- et c'est qqch de nettement plus important que d'écouter Kevin qui va faire une crise pour gagner 3 cycles sur les appels de fonctions virtuelles ^^


Dans ce nouveau préprocesseur malloc sera utilisé parce que ce sera plus du C with classes que du Java. Ainsi, la gestion des chaînes se fera comme en C. Dans le cas où je fournirais, par la suite, un API entièrement OO pour les chaînes, il est vrai qu'une allocation plus performante deviendrait intéressante. Par contre, si l'on veut de la performance lorsque l'on concatène "score: "+score+" (high="+highscore+")", on utilise un string buffer plutôt qu'instancier 3 objets. Je pense qu'une méthode d'allocation plus performance apporterait des gains linéaires.

Cependant, je ne sous estime pas la valeur d'une telle chose. C'est juste que ce n'est pas dans mes priorité, mais je serais plus que content si tu serais intéressé à contribuer au projet.



Je pense pas que ça soit vraiment un pb, en tout cas si le compilateur C++ -> C est "intelligent" et ne se limite pas à un préprocesseur quasi-textuel : tu parles de légèreté, par exemple le compilo C++ -> C peut parfaitement être capable de déterminer quelles sont les fonctions virtuelles qui sont vraiment nécessaires au programme, s'il connaît l'intégralité du programme :) (c'est nettement plus délicat en compilation séparée, mais sur TI la compilation séparée n'est pas nécessaire)


Si je veux pouvoir optimiser comme je l'entend, des compilations intégrales seront obligatoires. Par contre, ce ne sera pas un cauchemar de logistique de proposer une compilation par module optionnelle pour les plates-formes où la taille de l'exécutable n'est pas une préocupation.


Par contre c'est vrai qu'il faut sûrement un peu plus que le C standard : si on veut un GC ou une gestion des exceptions, il faut que le compilo soit capable de dire où il a stocké les objets si on veut éviter d'appeler penser_a_liberer(objet) à chaque exécution de la fonction ^^


C'est pourquoi je vais partir avec l'idée de faire un support des classes en C léger, optimisé en taille et performant, plutôt que quelque chose de 'full featuré' comme Moka.
    
./Post n°53   Marquer comme non lu.
Quésoft Ecrit le: Vendredi 20 octobre 2006 à 01:24 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Kevin Kofler :
Sauf qu'a priori, Quésoft m'a plutôt l'air parti pour le préprocesseur "quasi-textuel". :(


Dans quel sens ? Il me semble que j'ai été assez explicite quant à l'importance que les méthodes soit appelé statiquement lorsque c'est possible, que les méthodes non utilisées soient retirées, etc.

Utiliser les structures en C est déjà lexicographiquement semblable à utiliser des objets dans un langage OO, alors c'est sûr que sera assez direct comme préprocessing.

Pis c'est quoi ce :(. De ce que je sais, le support de l'orienté objet est pas mal la chose dont KK care le moins au monde, non ?
    
./Post n°54   Marquer comme non lu.
Quésoft Ecrit le: Vendredi 20 octobre 2006 à 06:34 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Je vais commencer demain à programmer le parsing des classes. J'ai donc de besoin de votre aide côté specs.

1. Les fichiers sources
Le préprocesseur va garder intact le formatage du fichier source et ne touchera qu'aux déclaration de classe et aux mécanismes OO qu'il devra convertir dans les fonctions.

Qu'est-ce que l'on fait pour les packages ? Comme en java ? Des namespaces comme en C++/C# ? Quelles sont vos préférences ?

Je crois qu'il faut permettre des déclaration de classe dans n'importe quel des fichier de source C, mais devrait-on avoir des fichiers (extension .java ou une autre) pour contenir spécifiquement une ou plusieurs classes ? Recommander de placer les classes dans des .h ?

2. Les objets locaux

Selon moi, même les objets locaux doivent être manipulés comme des référence (passage de l'adresse lorsque spécifié en paramètre, etc.). Quelle syntaxe utiliser pour déclarer un objet comme local ?

- Comme en C++, les objets sont locaux 'par défaut'. Si on veut un objet alloué dynamoquement on déclare un pointeur.
- Mot clef (e.g. 'local Object o;') ?

Moi mon goût va à des objets par référence par défaut, mais vous en pensez quoi ?

Pour les constructeurs, c'est facile: on passe l'objet local par adresse juste en dessous de la déclaration (s'il y a un constructeur pour cet objet). Par contre, les destructeurs, c'est plus difficile. Moka plaçait les objets locaux dans un vecteur. Ainsi, si le programme était quitté sans quitter le scope où avait été déclaré l'objet, il était finalizé par une boucle dans une fonction atexit. Cette solution a le désavantage d'augmenter sensiblement la taille du programme, alors je me demandais si vous avez des solutions plus efficaces. La solution la plus simple reste bien sur de ne pas permetre les classes ayant un destructeurs d'être utilisées localement, mais ça fait perdre les objets locaux de leur charme.

3. Visibilité des classes

Est-ce que l'on offre une caractéristique de visibilité pour les classes (e.g. public: disponible pour tous, private: juste dans le fichier de source actuel, protected: juste dans le package) ?

4. Appel du constructeur de la super classe
Normalement, pour respecter la philosophie OO, tous les constructeurs doivent appeler l'un des constructeurs de la superclasse (cela permet de respecter la notion d'encapsulation: le programmeur de la sous classe ne doit pas se soucier de l'initiation des variables private de la superclasse). Bien sûr, s'il n'y a pas de constructeur de défini pour aucune des superclasse, l'optimization évitera qu'une fonction dummy soit créée/invoquée inutilement. Je propose que l'on reste avec ce que java propose:

- this(params) appel un constructeur de cette classe
- super(params) appel un constructeur de la super classe. super() est toujours valide.

Lorsqu'une classe spécifie un constructeurs sans code à l'intérieur, le préprocesseur va 'faire semblant' qu'un tel constructeur existe, mais ne produira pas de fonction pour ce constructeur.

Je propose aussi de garder le mot clef super de java pour invoquer la version de la superclasse dune méthode:

public void toto () {
super.toto(); //appelle la version que cette méthode override
}

En tk, avec ça je vais pouvoir progresser un peu.
    
./Post n°55   Marquer comme non lu.
Pollux Ecrit le: Vendredi 20 octobre 2006 à 19:46 Déconnecté(e)    Voir le profil de Pollux Envoyer un email à Pollux Envoyer un message privé à Pollux  

Kevin Kofler :
Pollux :
C'est tout le problème de la gestion des exceptions en C++ : et tu vas énormément galérer pour faire qqch d'efficace en taille si le compilo C derrière ton préprocesseur n'a pas, lui aussi, une espèce de support des exceptions...

TIGCC gère les exceptions jusqu'à un certain niveau, cf. TRY etc. Le problème, c'est qu'il faut que certains trucs soient volatile pour que ça marche, par exemple ceci ne fonctionne pas:
HANDLE h=0;
TRY
  h=HeapAllocThrow(100);
FINALLY
  if (h) HeapFree(h);
ENDFINAL

alors que ceci fonctionne:
volatile HANDLE h=0;
TRY
  h=HeapAllocThrow(100);
FINALLY
  if (h) HeapFree(h);
ENDFINAL

(cf. la discussion sur TICT HQ pour toutes les subtilités qui entrent en jeu ici).

Non, ce n'est pas de ça que je parle : ton truc revient plus ou moins en C ansi à faire des setjmp/longjmp, et c'est évidemment très coûteux en temps et en taille si on s'amuse à faire ça à chaque déclaration d'une nouvelle variable... En plus comme tu dis ça pose des pbs avec l'allocation de registres.
Ce qu'il faudrait, c'est qu'en examinant le program counter ou la pile, on ait des métadonnées qui permettent de déterminer quelles sont les variables locales à détruire pour sortir proprement de la fonction ^^

Enfin c'est possible de façon un peu crade sans modification du compilo, si les stack frames sont activés : il suffit de mettre un marqueur magique aléatoire pour les objets à détruire, et rechercher le marqueur dans la pile... C'est un poil plus lent quand on lance une exception, mais c'est nettement plus rapide quand il n'y a pas d'exception, et le code sera nettement plus petit :)


C'est bien pour ça qu'il faut gérer les objets sur la pile!

Non, c'est pas suffisant, parce que par exemple pour les chaînes il faut stocker le contenu dans une zone malloc()ée... Idem pour les tableaux et tout ça ^^
Et puis évidemment il y a aussi le fait que souvent on ne peut pas se contenter de variables locales, et alors il faut bien stocker l'objet ailleurs que dans la pile...


Je m'en fous des 3 cycles, ce qui m'intéresse, c'est se passer de la vtable, ce qui permet au linker de ne linker que les méthodes effectivement utilisées. Si on a une vtable, on doit tout linker. C'est ce gain de taille qui m'intéresse. (Tu devrais le savoir, après tout ce temps. ;))

Ben nan, c'est pas parce qu'on a une vtable qu'on doit tout linker...


Euh, a priori il a GCC et c'est tout. Je ne vais pas m'amuser à rajouter des builtins pour ce genre de trucs dans TIGCC, s'il veut que son travail s'intègre bien à TIGCC, il doit coder un frontend GCC. De plus, il veut que son préprocesseur fonctionne avec n'importe quel compilateur C. Donc le C standard est tout ce qu'il a.

Je ne parle pas de rajouter des builtins, mais on est obligé d'utiliser au moins des trucs non-portables si on veut faire efficace :( (c'est évidemment mieux si le compilo a des builtins pour que ça soit optimal au niveau performance, mais au moins dans un premier temps c'est pas obligatoire)
    
./Post n°56   Marquer comme non lu.
Quésoft Ecrit le: Vendredi 20 octobre 2006 à 19:51 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

Personne n'est intéressé à donner ses préférences pour les specs ?
    
./Post n°57   Marquer comme non lu.
Quésoft Ecrit le: Vendredi 20 octobre 2006 à 19:58 Déconnecté(e)    Voir le profil de Quésoft Envoyer un email à Quésoft Visiter le site WEB de Quésoft Envoyer un message privé à Quésoft  

ah oui, question technique assez critique:

Pour les objets locaux, même en connaissant tout le contexte, comment déterminer statiquement qu'un objet local devra être finalisé dans ce genre de cas:


void a() {
  auto Object_featuring_finalization o;

  b();
}

void b() {
  exit();
}


Je ne vois pas quoi faire d'autre que ce que fait Moka (décrit plus haut)...
    
  :: Index » Forum Ti68K » Programmation C » Orienté objet avec TIGCC (113 réponse(s))
Pages : 3/6     « 1 2 [3] 4 5 6 » »|

.Répondre à ce sujet
Les boutons de code
[B]old[I]talic[U]nderline[S]trikethrough[L]ine Flip Hori[Z]ontallyFlip [V]erticallySha[D]ow[G]low[S]poilerCode [G][C]ite
Bullet [L]istList Item [K] Link [H][E]mail[P]icture SmileysHelp
Couleurs :
Saisissez votre message
Activer les smileys
     

Forum de Ti-Gen v3.0 Copyright ©2004 by Geoffrey ANNEHEIM
Webmaster: Kevin KOFLER, Content Admins: list, Server Admins: Tyler CASSIDY and Kevin KOFLER, DNS Admin: squalyl
Page générée en 60.61ms avec 18 requetes