1

Bonjour,

J'ai un petit problème pour utiliser une macro. Je vais l'expliquer avec un petit exemple : je déclare une structure quelconque, un tableau l'utilisant et un pointeur vers ce tableau :

typedef struct
{
const char *nom;
char age;
} PERSONNE;

PERSONNE gens[ 2 ]={
{"toto",10},
{"tata",20}
};

PERSONNE *p_gens=(PERSONNE*)&gens;

Pour accéder à une propriété du tableau en utilisant le pointeur, je peux par exemple écrire (*(p_gens+1)).nom (qui renvoie "tata"). Je voudrais maintenant utiliser une macro (nommons la "g") permettant d'écrire g(1).nom à la place du truc précédent. Comment faire ? Parce que ceci ne marche pas :

#define g(i) (*(p_gens+i));

Quand j'utilise cette macro, il y a une parse error. Quelqu'un a-t-il une idée ?
avatar
Time is on our side.

THE EXPERT 4 : topics/74978-the-expert-4
THE EXPERT 5 : topics/101326-the-expert-5
DUNE 2 : topics/111247-dune-2

2

Enlève le ; à la fin de ta macro.

Mais ça me semble bizarre que le code que tu as écrit compile sans erreur, car l'expression &gens n'est pas du type PERSONNE *, donc l'affectation p_gens = &gens; devrait poser problème.

Sinon, pourquoi tu n'écris pas simplement gens[i].nom ?
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. »

3

Pour cet exemple, TIGCC ne fait pas la différence quand il y a ou non un ;. Sinon pour le &gens, il y a effectivement un warning qui disparaît si je mets (PERSONNE*) devant. Mais le pb n'est pas là !

En fait le tableau "gens" (qui occupe beaucoup de place) n'est pas situé dans ma source mais dans un fichier séparé, si bien que je n'y ai accès que par l'intermédiaire d'un pointeur. Et j'aimerais pouvoir utiliser une macro afin de simplifier l'accès à ce tableau.

CBSoft -- qui crée le premier (?) jeu d'aventure "point & click" avec graphismes et scénario persos --
avatar
Time is on our side.

THE EXPERT 4 : topics/74978-the-expert-4
THE EXPERT 5 : topics/101326-the-expert-5
DUNE 2 : topics/111247-dune-2

4

Le tableau est dans un fichier externe au programme ou bien dans un fichier source différent de celui où tu l'utilises ?
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

Les deux. smile Le tableau est dans une source compilée à part (et l'exécutable devient donc externe). Cela me permet de stocker le tableau séparément car ce dernier prend de la place. De plus je peux ainsi compiler le tableau sans devoir recompiler tout le projet qui utilise 'gens'.
avatar
Time is on our side.

THE EXPERT 4 : topics/74978-the-expert-4
THE EXPERT 5 : topics/101326-the-expert-5
DUNE 2 : topics/111247-dune-2

6

Peut-être
#define DEREFSMALL(__p,__i) (*(typeof(&*(__p)))((unsigned char*)(__p)+(long)(short)((short)(__i)*sizeof(*(__p)))))
pour __p[__i], évidemment.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

7

top

#define g(i) (*(PERSONNE*)((unsigned char*)(p_gens)+(long)(short)((short)i*sizeof(*(p_gens)))))

Avec cette macro cela marche parfaitement ! Merci !

PS : mettre un &* n'est pas inutile ?
avatar
Time is on our side.

THE EXPERT 4 : topics/74978-the-expert-4
THE EXPERT 5 : topics/101326-the-expert-5
DUNE 2 : topics/111247-dune-2

8

CBSoft :
Sinon pour le &gens, il y a effectivement un warning qui disparaît si je mets (PERSONNE*) devant.

Oui, mais tu compliques les choses : "p_gens = gens" fait exactement ce que tu veux sans warning : en fait il n'y a pas besoin de mettre un & pour prendre l'adresse d'un tableau (le & devant un tableau n'est nécessaire que dans le cas ou tu as des tableaux a plusieurs dimensions et que tu veux transformer ton tableau de dimension 1 en une ligne d'un tableau de dimension 2 -- bref c'est tres rare et a n'utiliser que quand tu en as besoin).

Pour le &*, non il n'est pas inutile justement pour cette raison : p_gens est un PERSONNE[2], et tu ne peux pas transformer un pointeur quelconque en PERSONNE[2]; donc tu dois obtenir le type PERSONNE a partir de *p_gens, et obtenir PERSONNE* a partir de &*p_gens smile

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

9

Tu peux garder DEREFSMALL, parce qu'elle est générique, et plus efficace que p[ i ] - c'est pour ça qu'elle a été faite.

> PS : mettre un &* n'est pas inutile ?
Non, c'est nécessaire dans le cas des tableaux dont la taille est donnée. J'ai eu le problème sur un sprite unsigned short[16].

[EDIT: enlevé le tag italique]
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

10

OK, merci pour vos explications. smile
avatar
Time is on our side.

THE EXPERT 4 : topics/74978-the-expert-4
THE EXPERT 5 : topics/101326-the-expert-5
DUNE 2 : topics/111247-dune-2

11

CBSoft :
top

#define g(i) (*(PERSONNE*)((unsigned char*)(p_gens)+(long)(short)((short)i*sizeof(*(p_gens)))))

Avec cette macro cela marche parfaitement ! Merci !

PS : mettre un &* n'est pas inutile ?

A mon avis ça ne fonctionnera pas à tous les coups parce que tu as oublié de mettre des parenthèses autour du i. wink
#define g(i) (*(PERSONNE*)((unsigned char*)(p_gens)+(long)(short)((short)(i)*sizeof(*(p_gens)))))
Sinon juste une question, ça sert à quoi de faire (long)(short)? confus
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

12

a rien, le (long) est inutile... (par contre le (short) est utile, puisque sizeof() renvoie un unsigned short, donc la multiplication renvoie un unsigned short)

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

13

Je sais qu'il y a un truc à propos de (long) vs. (unsigned long). Mes address hacks pour les ROM_CALLs donnent du meilleur code quand il y a (long) que (unsigned long).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

14

si c'est le cas c'est un bug de tigcc...

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

15

16

Des façons de trouver les fonctions ou variables existant sous tous AMS, mais seulement définies dans la jump table sous une partie des versions d'AMS. Plus d'une dizaine de tels address hacks (il existe aussi des value hacks), dont un certain nombre de fonctions utiles de vat.h (que filelib réinvente différemment, d'ailleurs), pas tous faits par moi (voir push_internal_simplify dont le hack existe depuis longtemps).
La différence de taille totale entre AMS 1.xx et AMS 2.xx est suffisamment faible pour qu'on soit en droit d'être à peu près sûr que toutes les fonctions du CAS existent aussi sous AMS 2.03-. Ces address hacks sont inutiles parce qu'AMS 2.04+ les fournissent tous, avec les ROM_CALLs en F-Line (les fonctions du CAS étant par programmation et par nature lentes, il ne sert à rien de gagner 0% en passant en ROM_CALLs plus optimisés pour les appels).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

17

J'ai survolé rapidement le topic.... je comprends pas ce qu'il veut faire de si particulier qui empèche de faire betement gens[i] ?

18

en quoi DEREFSMALL(p,i) est plus efficace que p[i] ?
p[i] n'est pas equivalent à *(p+i*sizeof(*p)), et donc à DEREFSMALL ?
avatar

19

Si, mais il semble que TIGCC ne génère pas un code aussi optimal que lorsqu'on lui mâche le boulot.
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. »

20

Kevin Kofler a dit:

p_gens[ i] n'est absolument pas équivalent à (*(PERSONNE*)((unsigned char*)(p_gens)+(long)(short)((short)(i)*sizeof(*(p_gens))))
La deuxième formulation est optimale pour le processeur, la première a un comportement très différent si on a un i plus gros que 32768/sizeof(*p_gens)!!! Et donc la première ne peut pas être optimisée en la 2ème.

21

J'ai diminué la taille de la version de tthdex qui ne sortira probablement jamais d'une centaine d'octets en utilisant DEREFSMALL sous sa forme ASM inline avec opérandes C.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

22

jfg> et si i est un signed short ?

23

Essaie :-)
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.