Lionel Debroux (./2) :
Doit y a voir un problème de déclaration, non ?
Oui. Il faut soit que tu #include le fichier qui contient les strings, soit que tu déclares les strings dans un troisième fichier inclus par le source principal. Cette deuxième solution étant préférable si tu comptes faire plusieurs fichiers source.(pour ne pas faire #include des strings dans les fichiers source - avec TIGCC/GCC4TI qui comporte un mergeur de constantes, ça n'aura pas de conséquences sur la taille, mais sur la plupart des environnements de développement, il n'y en a pas, donc ce n'est pas une bonne habitude à prendre).
Attention...
Une chaîne de type:
char mastring[] = "toto";ne sera
jamais mergée par le mergeur de constantes (parce qu'elle n'est pas constante

).
Une chaîne de type:
const char mastring[] = "toto";ne sera mergée par le mergeur de constantes que si on utilise l'option
-fmerge-all-constants de GCC, désactivée par défaut (parce que normalement des tableaux différents doivent avoir des adresses distinctes).
La bonne solution pour bénéficier du mergeur de constantes est d'utiliser directement "toto" quand on en a besoin, genre:
DrawStr(0,0,"toto",A_REPLACE);ou à la limite de mettre un
#define dans le header:
#define mastring "toto"Les fichiers de chaînes de caractères, ça fait très "assembleur", ce n'est pas du tout la bonne solution en C. (Je signale au passage que toutes les chaînes d'outils modernes font du constant merging.)
Avec "-mpcrel -Wa,-l", le compilo utilisera des ea PC-relatifs, dans la mesure du possible (par exemple: jsr, bsr, lea et en ea source pour les instructions data movement, mais pas en ea destination pour les instructions data movement).
-mpcrel donne normalement du code entièrement PC-relatif, même pour les écritures (ça passe par un
lea). Mais ça ne marche pas sur les tableaux de pointeurs, qui sont par définition relogés. Il faut utiliser
switch pour avoir une table de saut PC-relative.
Folco (./3) :
Concrètement, je mets ça dans un header :char * mastring;
Non.
Tu mets:
extern char mastring[];1. Il faut utiliser
extern pour une déclaration externe d'une variable, ce n'est que pour les fonctions qu'
extern est impliqué s'il y a juste le prototype et pas le code de la fonction.
2. Un
char [] n'est pas un
char *, il y a des endroits où c'est différent et ceci en est un!
3. Faire une variable de type
char * n'est pas une très bonne idée parce que ça te fait un pointeur relogé qui ne sert à rien à part ralentir l'accès à ta variable. (En revanche, ça permet de bénéficier du constant merging, ce que le
char [] ne permet pas. La bonne solution pour n'avoir aucun des deux inconvénients, c'est de ne pas utiliser des variables pour tes chaînes constantes du tout, cf. plus haut. Le C n'est pas l'assembleur.)
Je veux faire ça :
str1 : "abc",0
str2 : "abc",0
str3 : "abc",0
table :
dc.w label-str1
dc.w label-str1
dc.w label-str1
et dans le source :
move.w table(pc,d0.w),d0
jsr label(pc,d0.w)
label:
etc...
J'ai besoin de ce genre de table. Faut que je fasse un tableau foutu comment en C poru arriver à ce résultat ?
Il faut que tu utilises l'instruction
switch.
En bref, je veux pas d'adresses relogées.
Je signale qu'il y a des relogements dans TIGCCLIB.
Folco (./5) :
Ok, merci. Au fait, le extern sert à quoi ? A dire que la variable n'est pas locale à un seul source ?
Non, cf. l'explication de Flanker. Pour une variable locale à un seul fichier source, c'est
static (et je conseille de mettre
static pour
toutes les variables ou fonctions qui ne sont pas déclarées
extern dans un header ni des fonctions exportées comme
_main ou
malib__0000, le compilateur peut s'en servir pour l'optimisation).
Et y a-t-il un type BOOL ou assimilé ?
Oui,
_Bool.
Lionel Debroux (./7) :
"Initialization discards qualifiers from pointer target type"
C'est par exemple quand on assigne une chaîne constante (de type const char *) à un char*, et que ce warning est activé.Pour corriger cela, soit tu déclares ton pointeur const char * (si tu ne veux pas modifier le contenu de la chaîne),
La bonne solution.
soit tu fais
char *string1 = (char *)"ABCDE";

Je signale que ça peut foirer grave, à cause du constant merging justement. On n'a pas le droit de modifier un string literal.
Si tu veux des tables de string ne générant pas de relocations, tu dois le faire à la main avec de l'ASM + de l'ASM inline avec opérandes C.

Il y a une solution en C pur:
const char strings[] = "foo\0bar\0toto";
short offsets={0,4,8};
#define STRING(n) (strings+offsets[n])
Brunni (./9) :
Pour le type bool tu peux écrire un truc du genre:
typedef enum {false=0, true=1} bool;

TIGCC définit déjà TRUE et FALSE.
typedef unsigned char bool;
Tu réinventes _Bool là.
cri_t cris[] = {criChien, criChat};
const char *textesCris[] = {"chien", "chat"};
Ça crée des relogements, ça.
Folco (./11) :
rararharhahrahrharhahr Je veux écrire ça :
dc.b "amqldjkf",0
dc.b "toeigj",0
dc.b 0On fait comment ? A part "amqldjkf\0toeigj\0\0" ? Je voudrais évidemment écrire ça de manière lisible ...
const char strings[] =
"amqldjkf\0"
"toeigj\0";
C'est entièrement équivalent à:
const char strings[] = "amqldjkf\0toeigj\0";(Et je signale que ton dernier \0 est inutile car rajouté automatiquement par la définition des chaînes de caractères en C.)
Brunni (./12) :
A toi de voir ce que tu préfères, mais une véritable table de saut au sens goto cris[ i ] n'est pas possible en C.
C'est
possible en GNU C.
Brunni (./13) :
Tu peux faire ça assez proprement en C de toute façon:
const char *texte = "chaine1\0chaine2\0chaine3";
const char *texte1 = texte, texte2 = texte1 + 8, texte3 = texte2 + 8;
Tu viens de créer 4 relogements là, tous les 4 inutiles! Cf. plus haut pour la bonne solution.