1

J'ai écrit une librairie (statique, rassure toi Kevin wink), mais j'aimerais proposer plusieurs niveaux d'utilisation : un niveau pour les utilisateurs expérimentés en leur fournissant des fonctions primaires, et ils auront quelques traitements à effectuer autour pour pouvoir s'en servir, mais en leur laissant faire ces traitements au lieu de les inclure dans la lib, je leur permet de les optimiser (les traitements) et en même temps, ça donne plus de souplesse à la lib. Et j'aimerais aussi un deuxième niveau qui soit plus simple à utiliser, et qui nécessiterait peu de code autour pour que tout fonctionne ; en fait les fonctions de ce niveaux utiliseraient les fonctions bas niveaux proposées pour les utilisateurs expérimentés, en rajoutant tous les traitements qu'il faut autour. Ces fonctions seraient simples à utiliser, mais à cause de leur nature même de fonctions générales, elles seraient moins souples et moins puissantes que les autres.
Bon, voilà le contexte, maintenant, voici mon problème : ma lib se décompose grossièrement en 2 fonctions de bas niveau qui se déclinent chacune en une variété de modes différents, ce qui fait qu'en tout, il y a 80 combinaisons différentes pour utiliser la lib. Et en ce qui concerne les fonctions de haut niveau, j'aimerais qu'elles soient simples à utiliser, et qu'on n'ait pas trop de choix de fonctions différentes, pour ne pas embrouiller l'utilisateur.
Donc, comme je l'ai dit précédemment, les fonctions de haut niveau appellent les fonctions de bas niveau, et la multitude des fonctions de bas niveau fait qu'il y a beaucoup de possibilités d'utilisation.
Il faut donc qu'à partir des paramètres passés à la fonction de haut niveau je puisse déterminer quel couple sous-fonctions de bas niveau je dois appeler pour correspondre à l'utilisation demandée.
*call_back2)(void*,short,short,void*));J'ai donc pensé à un truc comme ceci : void HautNiv(void (*call_back1)(short,void*,void*,void*),void (Où la première fonction de bas niveau a un prototype du genre void nom(short,void*,void*,void*); et la deuxième void nom(void*,short,short,void*); (enfin, on verra toute à l'heure que ce n'est pas toujours le cas).
Cela permet à l'utilisateur de la fonction de haut niveau de choisir lui-même ce qu'il veut comme combinaison des deux fonctions de bas niveau.
voir utiliser les fonctions de haut niveau. Pour pallier à ce problème, je déclare des macros avec des noms explicites du genre :void BasNiv1A(short,void*,void*,void*); void BasNiv3C(void*,short,short,void*); #define Type_1_A Fonction1A #define Mode_3_C Fonction3C HautNiv(Type_1_A,Mode_3_C); // L'appel de la fonctionBien sûr, vous allez me dire que ça n'est pas du tout pratique à utiliser parce que l'utilisateur des fonctions de haut niveau sera obligé de connaître toutes les fonctions de bas niveau pour pouCe qui devrait être relativement facile à utiliser.

Mais en fait, il y a un léger problème, c'est le fait les fonctions de bas niveau n'ont pas toutes le même prototype. Je peux faire un transtypage pour éviter un warning à la compilation ; et pour les paramètres (lors de l'appel de la sous-fonction à partir de la fonction de haut niveau), ce n'est pas pratique du tout, ça m'oblige à passer le maximum de paramètre possible alors que certaines fonctions n'en ont pas besoin.
Exemple illustratif :
Supposons que la fonction correspondant au mode 2B prenne 3 paramètres et la fonction correspondant au mode 2C en prenne 4. J'utilise une fonction de haut niveau, et à l'intérieur de cette fonction, la fonction correspondant au mode choisi (2B ou 2C dans notre cas) est appelée car je passe son adresse à la fonction de haut niveau. Mais la fonction de haut niveau n'a aucun moyen de savoir s'il s'agit de la sous-fonction qui correspond au mode 2B (3 paramètres), ou 2C (4 paramètres), donc pour pouvoir assurer un bon fonctionnement, la fonction de haut niveau doit passer 4 paramètres, pour être sûre qu'au cas où la fonction demandée est la 2C il n'y ait aucun problème.
Seulement c'est dommage de passer à chaque fois ce paramètre alors qu'il n'est pas indispensable.

Donc déjà, est-ce que vous avez une solution plus simple pour gérer tous les modes ?
Sinon, avez-vous des idées pour contourner mon problème ?
Merci smile
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

2

C'est pour ExtGraph 2 ? top

En fait je ne comprends pas exactement ce que tu veux faire : la fonction HautNiv est écrite en C ? Et je présume qu'elle fait partie de la lib ?

Ensuite, est-ce que tu comptes faire des manipulations sur tes fonctions ou bien est-ce que l'appel à HautNiv sera toujours de la forme HautNiv(<identificateur1>,<identificateur2>) où les deux identificateurs sont réellement des identificateurs au sens lexical ? (i.e. pas de cast, pas de [], etc...) Comme je pense que c'est pour l'utilisateur "de base", c'est probablement possible de supposer que c'est vérifié et qu'on ne fait pas de truc tordu sur les fonctions.

Enfin, est-ce que c'est viable de dupliquer le code de HautNiv pour distinguer selon que la fonction n°1 a 2 ou 3 paramètres, ou est-ce que ça prendrait trop de place pour le gain en vitesse ?

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

3

Pollux :
C'est pour ExtGraph 2 ? top
C'est une autre lib, mais elle sera probablement intégrée à ExtGraph quand elle sera terminée.
En fait je ne comprends pas exactement ce que tu veux faire : la fonction HautNiv est écrite en C ? Et je présume qu'elle fait partie de la lib ?
Elle est écrite en ASM, comme toutes les autres fonctions, et elle fait partie de la lib, oui.
Ensuite, est-ce que tu comptes faire des manipulations sur tes fonctions ou bien est-ce que l'appel à HautNiv sera toujours de la forme HautNiv(<identificateur1>,<identificateur2>) où les deux identificateurs sont réellement des identificateurs au sens lexical ? (i.e. pas de cast, pas de [], etc...) Comme je pense que c'est pour l'utilisateur "de base", c'est probablement possible de supposer que c'est vérifié et qu'on ne fait pas de truc tordu sur les fonctions.
Je ne suis pas sûr de bien comprendre ce que tu me demandes, mais les appels à HautNiv doient être de la forme HautNiv(<ident1>,<ident2>); où <ident1/2> est l'adresse d'une fonction (donc son nom, rien de plus). Mais comme la fonction HautNiv prend en paramètre l'adresse d'une fonction ayant un prototype x, si la fonction dont on lui passe l'adresse n'a pas exactement ce prototype, je rajouterai un transtypage pour ne pas avoir de problème de compilation.
Enfin, est-ce que c'est viable de dupliquer le code de HautNiv pour distinguer selon que la fonction n°1 a 2 ou 3 paramètres, ou est-ce que ça prendrait trop de place pour le gain en vitesse ?
Non, ça ne prendrait pas beaucoup de place, je pense (je n'ai pas encore écrit la fonction HautNiv donc je ne suis pas sûr sûr), mais je n'ai pas trop envie de séparer ce cas, j'ai déjà peur d'avoir plusieurs fonction de haut niveau, je n'ai pas trop envie d'en avoir un paquet.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

4

Sasume
:
Enfin, est-ce que c'est viable de dupliquer le code de HautNiv pour distinguer selon que la fonction n°1 a 2 ou 3 paramètres, ou est-ce que ça prendrait trop de place pour le gain en vitesse ?
Non, ça ne prendrait pas beaucoup de place, je pense (je n'ai pas encore écrit la fonction HautNiv donc je ne suis pas sûr sûr), mais je n'ai pas trop envie de séparer ce cas, j'ai déjà peur d'avoir plusieurs fonction de haut niveau, je n'ai pas trop envie d'en avoir un paquet.
Enfin en même temps le gain en vitesse, je ne sais pas s'il serait très présent parce que le passage du paramètre correspondrait juste à un move.l n(a0),d2.

Mais je voulais quand même savoir ce que vous en pensiez, savoir si je fais des détours pour arriver à un truc qui pourrait être fait bien plus simplement, selon une méthode à laquelle je n'aurais pas pensé.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

5

(donc son nom, rien de plus)

OK, c'est ce que je voulais savoir. Donc on peut faire fonction##_nombre_de_paramètres.
Mais comme la fonction HautNiv prend en paramètre l'adresse d'une fonction ayant un prototype x, si la fonction dont on lui passe l'adresse n'a pas exactement ce prototype, je rajouterai un transtypage pour ne pas avoir de problème de compilation.

Oui, mais ça c'est la lib qui le rajoute. On peut parfaitement faire (void(*)(...))fonction##_fonction smile
Non, ça ne prendrait pas beaucoup de place, je pense (je n'ai pas encore écrit la fonction HautNiv donc je ne suis pas sûr sûr), mais je n'ai pas trop envie de séparer ce cas, j'ai déjà peur d'avoir plusieurs fonction de haut niveau, je n'ai pas trop envie d'en avoir un paquet.

De toute façon si tu veux éviter d'avoir à passer un paramètre, tu es obligé d'avoir un code différent, non? (ou alors, code auto-modifiant powa, mais ça n'est rentable que si tu as une boucle qq part). Et comme tu as été très très évasif sur la nature de toutes les fonctions (et de la lib), on ne sait pas d'où viennent ces fameux paramètres optionnels, s'ils ont été passés par l'utilisateur, si le paramètre n°3 a toujours le même sens les fois où il existe (même s'il n'est pas tjs nécessaire), si c'est le résultat d'un calcul, si c'est une variable globale...

En tout cas, s'il y a une possibilité d'optimisation, elle passe certainement par une manipulation préprocesseur du style fonction##_machin smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

6

cross post neutral
Sasume
:
Sasume
:
Enfin, est-ce que c'est viable de dupliquer le code de HautNiv pour distinguer selon que la fonction n°1 a 2 ou 3 paramètres, ou est-ce que ça prendrait trop de place pour le gain en vitesse ?
Non, ça ne prendrait pas beaucoup de place, je pense (je n'ai pas encore écrit la fonction HautNiv donc je ne suis pas sûr sûr), mais je n'ai pas trop envie de séparer ce cas, j'ai déjà peur d'avoir plusieurs fonction de haut niveau, je n'ai pas trop envie d'en avoir un paquet.
Enfin en même temps le gain en vitesse, je ne sais pas s'il serait très présent parce que le passage du paramètre correspondrait juste à un move.l n(a0),d2.
Mais je voulais quand même savoir ce que vous en pensiez, savoir si je fais des détours pour arriver à un truc qui pourrait être fait bien plus simplement, selon une méthode à laquelle je n'aurais pas pensé.


OK, d'accord, c'est un passage par registres, et tu vas juste chopper un élément d'une structure. Perso je crois que la seule solution viable dans ton cas est de faire un HautNiv_2param et un HautNiv_3param, ou bien tout simplement de passer les 3 params à chaque fois.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

7

J'avoue que je n'avais pas pensé à utiliser le '##', j'avais complètement oublié que ça existait. Je vais voir ça, merci bisoo
Sinon, en ce qui concerne le code auto-modifiant, j'y ai pensé, mais ça ne serait pas rentable à mon avis.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

8

Oui, si tu n'es pas dans une boucle, le code auto-modifiant n'est vraiment pas rentable...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

9

Sasume :
J'avoue que je n'avais pas pensé à utiliser le '##', j'avais complètement oublié que ça existait. Je vais voir ça, merci bisoo Sinon, en ce qui concerne le code auto-modifiant, j'y ai pensé, mais ça ne serait pas rentable à mon avis.

Ca sert à quoi le ## ?
Site : http://www.phareaway.com/
Membre du groupe Phare Away et webmaster du site

10

avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

11

Tu peux etre plus clair ?

12

Le lien explique tout. smile
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

13

Nan, je parlais du probleme de Sasume. Le ## je connais et j'utilise (presque) tous les jours.

14

Je n'ai pas vraiment de conseils à donner sur les macros, mais pour les fonction, je te conseille déja d'utiliser un typedef pour les pointeurs de fonction, c'est plus facile de s'y retrouver ensuite. Et si les fonction n'acceptent pas toutes le même nombre de paramètres, en ce qui concerne le cast tu peux le faire dans les macros...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

15

PpHd
: Nan, je parlais du probleme de Sasume. Le ## je connais et j'utilise (presque) tous les jours.

Ah, tu me rassures. smile Je me posais déjà des questions. grin
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

16

Link
: Je n'ai pas vraiment de conseils à donner sur les macros, mais pour les fonction, je te conseille déja d'utiliser un typedef pour les pointeurs de fonction, c'est plus facile de s'y retrouver ensuite.
onctionHautNiv(Mode mode); // Appel de la fonction : FonctionHautNiv(Mode_1_A);
C'est ce que j'ai fait. Et ça permet à l'utilisateur une vision opaque des choses :void FonctionBasNiv_1_A(short,void*,void*);
#define Mode_1_A FonctionBasNiv_1_A
typedef void (*Mode)(short,void*,void*);

void F
L'utilisateur n'a pas besoin de savoir ce qu'est mode, il mettra simplement l'identificateur correspondant à ce qu'il veut.

PpHd> J'ai plusieurs fonctions qui permettent de faire différentes choses. Ces fonctions sont écrites de façon à être les plus rapides possible, et pour les utiliser, il y a un tas de code à rajouter autour pour pouvoir s'en servir (code que ces fonctions ne gèrent pas, de façon à laisser l'utilisateur optimiser sa façon de les gérer).
Afin de simplifier l'utilisation de la lib, j'écrit des fonctions qui utilisent les premières fonctions, et qui en plus font tous les traitements intermédiaires nécessaires.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

17

Kevin Kofler :
Concaténer 2 tokens. http://tigcc.ticalc.org/doc/cpp.html#SEC18

ah oui, je me souviens avoir dû chercher l'explication lors de la compilation de FFTW wink
Site : http://www.phareaway.com/
Membre du groupe Phare Away et webmaster du site