60

Pourquoi ça marche pas ça ?
PlanesPtr = PlanesPtr & ~7;
Il me dit que les opérateurs sont invalides... On a pas le droit de jouer à ça avec un pointeur ?

edit -> Ca, c'est la solution propre ?
PlanesPtr = (void *)((long)PlanesPtr & ~7);
C'est pas un peu lourd ? En fait, on passe son temps à tromper le compilateur, alors que ça devrait très bien marcher ...

edit² -> ah oui, et puis on dit que l'asm c'est pas lisible après :
PlanesPtr = ((void *)((long)(PlanesHdPtr + 7) & ~7));
sick C'est peut-être qu'une question d'habitude, mais perso ce que ça veut dire, ç me saute pas aux yeux.

61

Tiens, voici le code fourni :
	move.l PlanesHdPtr,%d0
	addq.l #7,%d0
	moveq #-8,%d1
	and.l %d0,%d1
	move.l %d1,PlanesPtr

C'est bien le code attendu. Mais pourquoi ne râle-t-il pas, je lui ai jamais dit que ~7 était un long, comment le sait-il ?

62

en même temps dire que l'asm n'est pas lisible n'implique pas que le C le soit, c'est quand même assez difficile de faire pire que le C comme syntaxe ^^

Qu'est-ce que tu veux faire avec PlanesPtr au juste, il représente quoi ? suivant ce que tu fais ça peut être plus logique de le déclarer comme un long et de ne le caster que quand tu veux déréférencer.

edit : il fait des cast implicites dans certains cas (enfin ça s'appelle promotion je crois), notamment entre les différents types numériques. En l'occurrence, dans une expression arithmétique comme là, il regarde quel est le type le plus général parmi tous les opérandes et les convertit tous vers ce type. Ça vaut pour les long mais aussi pour les float : si une expression contient un float tout est converti en float (et alors / ne désigne plus la division entière mais la division flottante, etc.)
Enfin, en gros c'est ça, en détail ça doit être une spécification imbitable comme d'hab (par exemple je ne sais pas dans quel ordre les conversions sont appliquées s'il y en a plusieurs à faire...)

Il fait aussi des cast implicites d'entier vers pointeur par exemple, mais dans ce cas tu as un warning.
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

63

Folco (./60) :
C'est pas un peu lourd ? En fait, on passe son temps à tromper le compilateur, alors que ça devrait très bien marcher ...

C'est normal, parce que tu passes ton temps à faire des trucs dégueulasses, non portables et que tu réfléchis d'abord ASM avant de réfléchir C ^^
Et effectivement c'est la bonne manière de faire ce que tu veux. Faut bien se rendre compte qu'en temps normal tu n'as aucune raison de faire ça, donc c'est normal que le C te complique la vie; ça permet de t'en rendre compte et de t'éviter de faire ce genre de trucs accidentellement. Tu peux avoir besoin de le faire avec les index d'un tableau, dans ce cas là tu travailles avec des entiers => logique, mais avec des adresses en mémoire ça donne presque toujours du caca wink
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

64

Ok. En fait, sur TI, on est assez confronté à ce genre de cas, on reste très près de la machine, même en C.

Sally -> Merci, je pourrai creuser tout ça quand j'aurai récupéré mon bouquin.
Le code est le suivant :
	if(!(PlanesHdPtr = HeapAllocPtr(LCD_SIZE*4+8)))						//try to alloc planes to save work
	{
		ST_helpMsg("Not enough RAM to run GrayTool");
		ngetchx();
		return;
	}
	PlanesPtr = ((void *)((long)(PlanesHdPtr + 7) & ~7));
	GribOn(PlanesPtr,PlanesPtr+LCD_SIZE);

Or HeapAllocPtr est de type void*, donc j'ai donné ce type à PlanesHdPtr et PlanesPtr. C'est peut-être pas une bonne idée ?

65

Typiquement pour aligner de la mémoire tu as memalign en principe. Bon là ça n'ira pas avec les handles. C'était pour info ^^
Et en général tu donnes à tes pointeurs le type avec lequel tu y accèdes. Ici les pixels étant 1 bit ça n'a pas bcp de sens, donc tu fais ce que tu veux.
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

66

Ok ! Donc j'imagine qu'il faudrait un long pour des pixels codés sur 3 octets + canal machin.

67

Les pointeurs sont considérés comme "opaques" en C, tu n'es pas censé faire de manipulation sur leur valeur numérique. (Bon en l'occurence tu t'en fous puisque l'architecture hardware est fixe et connue pour toi, mais à la base c'était censé être un langage portable).

D'ailleurs, renseigne-toi sur ce qui dépend de l'implémentation (machine et/ou compilateur) en C, tu vas être surpris. En vrac : la taille et la représentation des entiers (pas forcément du binaire et du complément à 2), l'endianness, l'ordre et l'espacement des éléments dans une structure, l'effet d'un décalage de bits sur un nombre signé, l'ordre d'évaluation des expressions où il y a des pré/post incrémentations....

Et si tu commences à attaquer le hardware, lit cet article, ça t'évitera de sacrés maux de tête à chercher pourquoi ton prog déconne aléatoirement.
Brunni (./63) :
Faut bien se rendre compte qu'en temps normal tu n'as aucune raison de faire ça, donc c'est normal que le C te complique la vie
Ouais, enfin, tu as déjà essayé de faire un programme vraiment portable en C ? C'est tout aussi merdique grin
(je parle d'un truc non trivial qui devrait marcher dans n'importe quelle implémentation valide de la norme, y compris les cas tordus autorisés...)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

68

Zerosquare (./67) :
Les pointeurs sont considérés comme "opaques" en C, tu n'es pas censé faire de manipulation sur leur valeur numérique. (Bon en l'occurence tu t'en fous puisque l'architecture hardware est fixe et connue pour toi, mais à la base c'était censé être un langage portable).
D'ailleurs, renseigne-toi sur ce qui dépend de l'implémentation (machine et/ou compilateur) en C, tu vas être surpris. En vrac : la taille et la représentation des entiers (pas forcément du binaire et du complément à 2), l'endianness, l'ordre et l'espacement des éléments dans une structure, l'effet d'un décalage de bits sur un nombre signé, l'ordre d'évaluation des expressions où il y a des pré/post incrémentations....

La conversion impossible d'un pointeur vers une fonction en un pointeur vers des données, également, je suppose qu'il y a également l'alignement des données ne mémoire, la valeur NULL, ...
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

69

Folco > ah ok, je n'imaginais pas ça. Je ne savais même pas que ça avait une utilité d'aligner sur une adresse multiple de 8 sur TI cheeky. Je ne sais pas quelle est la meilleure solution, mais je ferais peut-être plutôt :

unsigned long PlanesHdAddr;
unsigned char* PlanesPtr; /* unsigned char = octet, ça peut être autre chose */
if (!(PlanesHdAddr = (unsigned long)Heap...
...
PlanesPtr = (unsigned char*) ((PlanesHdAddr + 7) & ~7);

ça me semble un peu plus logique/propre, mais bon ^^.

Un truc qui ne te sert pas en l'occurrence mais peut t'intéresser, c'est que si tu as un pointeur vers un type le compilateur s'arrange tout seul pour l'aligner sur une adresse permettant de lire ce type. Si je ne me trompe pas, si tu castes un pointeur void* vers int* il doit ajouter une instruction pour obtenir la parité, en particulier.
Par contre il me semble que sur TI il n'est jamais *nécessaire* d'avoir un alignement meilleur que ça donc il ne le fera sans doute jamais tout seul. Sauf peut-être avec certaines optimisations...

edit : j'ai ajouté unsigned devant long, tu devrais le faire aussi même si tu gardes ta solution. (Bon ça ne change rien pour une addition, mais bon...)

d'ailleurs quelques trucs utiles si tu joues beaucoup avec la mémoire :
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long longword;

j'ai utilisé ça dans foblub, ça allège beaucoup hehe
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

70

Sally (./69) :
Par contre il me semble que sur TI il n'est jamais *nécessaire* d'avoir un alignement meilleur que ça donc il ne le fera sans doute jamais tout seul.

Meilleur que ça, c'est-à-dire meilleur que pair ? (sur TI, tu peux lire un octet à une adresse impaire, mais si tu veux lire des word ou des longwords, il faut une adresse paire ; je reprécise vu que j'ai un doute avec ta phrase grin )
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

71

./67> C'est clair que le C n'est pas terrible, mais bon je vais pas coder en Ada non plus hein grin
Si c'est au moins portable sur une famille de µC c'est déjà pas mal hehe surtout qu'un code n'est jamais vraiment portable en soi, vu que c'est un compromis entre souplesse et performances.
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

72

oui meilleur que pair, tu peux lire n'importe quoi à une adresse paire même si elle est congrue à 2 modulo 4 non ? c'est ce que je voulais dire ^^. Donc le compilateur n'a pas de raison de spontanément aligner sur un multiple de 8, sauf peut-être certaines optimisations.
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

73

Sally (./62) :
c'est quand même assez difficile de faire pire que le C comme syntaxe ^^

Et pourtant... J'en connais un qui commence avec la même lettre, et se termine avec deux signes "+" cheeky couic2

74

Oui j'ai failli le dire, mais je le connais (très) mal cheeky
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

75

Sally (./69) :
Folco > ah ok, je n'imaginais pas ça. Je ne savais même pas que ça avait une utilité d'aligner sur une adresse multiple de 8 sur TI mod.gif . Je ne sais pas quelle est la meilleure solution, mais je ferais peut-être plutôt :

long PlanesHdAddr;
unsigned char* PlanesPtr; /* unsigned char = octet, ça peut être autre chose */
if (!(PlanesHdAddr = (long)Heap...
...
PlanesPtr = (unsigned char*) ((PlanesHdAddr + 7) & ~7);

ça me semble un peu plus logique/propre, mais bon ^^.

Le truc, c'est qu'il me parait plus logique que ce soit un pointeur vers rien de connu (un void) qu'un pointeur sur des chars. Au pire, il faudrait l'écrire DSCREEN *PlanesPtr. Ca serait pas mieux ça ?

76

C'est pas terrible en effet, mais t'as pas vraiment le choix : les pointeurs sont typés en C, tu ne peux quasiment rien faire avec un pointeur void, à part le caster vers un pointeur typé. En pratique, void ça sert essentiellement comme étape intermédiaire quand un type peut varier à l'exécution (Exemple : une fonction qui accepte plusieurs types de pointeurs en entrée, suivant la valeur d'un flag).

Il me semble que certains compilos interprètent les pointeurs void comme des pointeurs vers un char, mais je doute que ce soit standard.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

77

Pour grib, je te laisse diriger le fork, j’ai la flemme de m’en occuper tongue
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. »

78

Il me semble que certains compilos interprètent les pointeurs void comme des pointeurs vers un char, mais je doute que ce soit standard.

GCC fait ça, en effet (d'où l'option -Wpointer-arith), mais ce n'est pas standard, et je ne pense pas qu'il soit prévu que ça fasse partie de C++0x...
En particulier, ça nécessite que sizeof(void) == 1 (trifus)
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

79

Sasume (./77) :
Pour grib, je te laisse diriger le fork, j’ai la flemme de m’en occuper tongue

On peut pas vraiment parler de fork : j'ai corrigé des ptits bugs et rajouté une fonction supplémentaire (GribOnAllocPlanes2, plus courte et un poil différente de ta fonction). Tu m'autorise à releaser ça sous GPL ?

80

Oui oui, pas de problème !
(je kiffe ta signature trilove)
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. »

81

Ok, merci !

(ben quoi, c'est pas moi qui l'ai inventée cette phrase ^^)

82

Folco (./60) :
PlanesPtr = ((void *)((long)(PlanesHdPtr + 7) & ~7));
trilove
pour le moment je me contente de faire un programme kimarche-based
trilove²

83

./75 > ben void*, c'est un pointeur que tu ne peux pas déréférencer, donc c'est un peu bizarre cheeky (en effet déréférencer le pointeur signifierait que tu veux lire ou écrire une valeur de type void, ce qui n'existe pas). En fait ça sert uniquement à représenter une adresse où on ne sait pas ce qu'il y a, c'est donc surtout utilisé par les fonctions de manipulation de mémoire (malloc/free, memcpy), ou dans des cas particuliers comme dit 0².

Le type que tu donnes à ton pointeur dépend de ce que tu as l'intention de mettre dans ce buffer que tu as alloué. Dans certains cas, c'est plutôt la façon dont tu veux y accéder : typiquement, si tu veux représenter un plan de gris, c'est juste une série de bits, mais évidemment tu ne peux pas définir un pointeur vers des bits, donc le plus général c'est un pointeur vers des octets (unsigned char *). Si occasionnellement tu veux accéder à un mot, tu castes ponctuellement. Si tu n'y accèdes que via des mots, tu peux le définir comme unsigned short *, mais dans le cas de l'écran ça m'étonnerait que ce soit le cas, enfin j'en sais rien mais bon ^^.

Exemple :
unsigned char* buffer = qqch;
buffer[offset] = 0;
/* écrit l'octet 0 à l'adresse buffer + offset */
((unsigned short*) buffer)[offset] = 0;
/* écrit le mot 0 à l'adresse buffer + 2 x offset. Attention à ce facteur 2 ^^
edit : Kevin dit qu'il n'arrondit pas automatiquement à une adresse paire sad, donc attention aussi */

Bon par contre j'avais crossé et pas lu le ./66, ici si je comprends bien tu représentes un pixel sur 4 octets ? donc à ta place je définirais une structure :

typedef struct {
unsigned char red; /* oui j'écris n'importe quoi je sais pas comment marchent les niveaux de gris tongue */
unsigned char green;
unsigned char blue;
unsigned char alpha;
} pixel;

ensuite tu déclares ton pointeur comme un pixel*.
Après cela, pointeur[n] désigne la structure correspondant au pixel numéro n (donc le n+1e), c'est-à-dire en l'occurrence celle qui se trouve 4 x n plus loin que là où pointe le pointeur. De même, pointeur + n pointe vers cette structure numéro n, donc l'addition rajoute 4n à l'adresse effective.
Pour accéder aux composants individuels de ta structure, deux solutions :
— pointeur[n].green ou bien
— pointeur -> green (qui est une abréviation de (*pointeur).green)

Et ensuite ce que tu peux faire c'est remplacer le 4 dans l'argument de HeapAllocPtr par : sizeof(pixel). Quel est l'intérêt ? c'est que si plus tard tu t'aperçois que tu as besoin d'autres informations pour représenter un pixel, tu n'auras qu'à rajouter le composant à la structure, et tu n'auras pas à modifier cet appel, ni rien de ce qui n'utilise pas le nouveau composant. happy
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

84

squalyl (./82) :
Folco (./60) :
PlanesPtr = ((void *)((long)(PlanesHdPtr + 7) & ~7));
trilove.gif

Et pourquoi un trilove ? Donne-moi ta vision des choses, chacun le fait ici grin (et tant mieux ^^)
Sally (./83) :
Bon par contre j'avais crossé et pas lu le ./66, ici si je comprends bien tu représentes un pixel sur 4 octets ? donc à ta place je définirais une structure :

Non, j'imagine juste, je n'utilise qu'un bit pour un pixel sur une 89 tu sais trioui grin

85

ah oui ok, donc j'avais raison d'imaginer que les 4 octets représentent red green blue et alpha cheeky

(sinon j'en sais rien moi, tu aurais pu vouloir associer plein d'informations à un pixel, enfin > un octet ça m'étonnait un peu, mais bon grin)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

86

Folco> trilove parce que rah, quand même, ce genre d'expression pour 3 opcodes 68k, ça rox grin (et je sais qu'on a pas le choix, les faut bien les cast ^^)

87

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 roll).

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";

sick bang

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.

sick

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;

sick
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.
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é

88

Kevin Kofler (./88) :
2. Un char [] n'est pas un char *, il y a des endroits où c'est différent et ceci en est un!


je l'ai en effet appris à mes dépends, mais EN QUOI c'est différent?

89

Folco (./23) :
void Draw (void);
void Draw()
{
DrawMenu(RootMenu);
}

Écris plutôt:
void Draw(void)
{
DrawMenu(RootMenu);
}

tout simplement. Et les () sont une très mauvaise habitude à prendre en C (ça signifie "prend n'importe quoi comme arguments" pour des raisons historiques), mets toujours (void).
Folco (./24) :
	short MaxLenght = 0;			//size of the greatest string
	short TmpLenght;				//size of current item

Je te signale qu'on écrit length, width, mais height. Cherche pas à comprendre. grin
Folco (./28) :
Ah ok, comme d'habitude il voulait son petit "const" kivabien. L'assembleur produit est identique, je me demande pourquoi il me fait chier avec ça, c'est sûrement un bug. embarrassed

Non, c'est pour éviter que tu écrases quelque chose que tu n'as pas le droit d'écraser. Le C n'est pas entièrement type-safe, mais il l'est beaucoup plus que l'assembleur qui te permet de mixer les données de nature différente n'importe comment.
Folco (./29) :
Il râle pas, alors que ItemPtr est un pointeur, et strlen un long. Ok, c'est la même taille. Je m'attendais à devoir faire un cast, c'est pas la peine. C'est normal ?

Oui, c'est normal, les adresses forment un espace vectoriel à une dimension. Dans un espace vectoriel, on peut ne considérer qu'un type de vecteurs (comme tu essaies de le faire), mais pour éviter des bêtises, il est plus judicieux de considérer des vecteurs de position et des vecteurs de direction. (En particulier, si tu travailles avec ces 2 classes de vecteurs, tu n'as pas besoin d'une origine.) Prends comme exemple le plan euclidien: un vecteur de position est un point, genre A, un vecteur de direction est un vecteur de type AB, où A et B sont des points. Tu ne peux pas ajouter 2 vecteurs de position, par exemple A+B n'a aucun sens. En revanche, tu peux ajouter un vecteur de direction à un vecteur de position, genre A+AB=B, B+AB=C tel que B est le milieu de AC etc. Tu peux aussi ajouter un vecteur de direction à un autre, genre AB+BC=AC. Et ben, avec les pointeurs, c'est pareil: les pointeurs sont des vecteurs de position, les entiers de type size_t les vecteurs de direction. Tu ne peux pas additionner 2 pointeurs, mais tu peux ajouter un entier à un pointeur et bien sûr tu peux additionner 2 entiers.

Soit dit au passage que l'espace vectoriel des pointeurs a une origine, NULL, mais l'arithmétique des pointeurs n'utilise pas cette origine, et en particulier l'utilisation de ptr1+(ptr2-NULL) pour additionner 2 pointeurs n'est pas prévue par le standard C (ça pourrait à la limite faire ce que tu attends, mais ce n'est pas portable du tout évidemment et franchement ça n'a aucun sens).
Folco (./35) :
Je voudrais savoir comment définir quelque part les 4 constantes caracères à la suite : {0,0,239,127}.

const SCR_RECT fullscreen={{0,0,239,127}};
Sinon, tu peux aussi utiliser directement &(const SCR_RECT){{0,0,239,127}} partout où tu en as besoin et ça sera unifié par le constant merging.
squalyl (./39) :
oui, j'ai oublié de dire, pour mater le code généré, ne pas oublier le flag -O0 (qui devrait s'appeler -fhuman-readable grin)

Euh, pas vraiment, ça pond du code affreux et inutilement compliqué, la sortie de -Os est souvent beaucoup plus lisible. (En revanche, -O2 et -O3 peuvent donner du code bizarre (mais rapide) dans certains cas.)
Folco (./41) :
Pour le moment, je reste en -o2 classique, l'assembleur se lit très bien et me parait bien foutu.

Pourquoi -O2 et pas -Os?
va juste falloir que je trouve comment dire à TIGCC d'utiliser le handler de f-line pour les ROM-calls, et non $c8

Project / Options / Compilation / Program options... / Reloc Format / Choose the ROM call format that suits your needs: F-Line
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é

90

Merci pour tout Kevin. Je reprends pas tout ce que tu m'as dit, mais tu m'as apporté bien des réponses. smile