240

Non, c'est peut-être un cas particulier qui a été introduit par commodité et qui n'a pas pu être conservé avec le C++ qui impose
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

241

Il me semble que tu peux pas faire un

void*malloc(size_t size);


char *blabla = malloc(1024);

sans au moins te prendre un warning...

Par contre l'inverse :

void memset(void *ptr, int value, size_t size);

permet de faire un

char blu[1024];
char *blabla = &(blu[0]);

memset(blabla, 0, 1024);

sans caster vers un void*

edit: parseur yNML tout pourite sad
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

242

heu oui en fait c'est cohérent avec ce que disait Sally, donc j'ai rien dit cheeky

(c'est même carrément un
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

243

Zephyr (./242) :
heu oui en fait c'est cohérent avec ce que disait Sally, donc j'ai rien dit cheeky

(c'est même carrément un

Ou même un
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

244

je sais pas pkoi mon proxy a décidé de tronquer les valeurs POST aujourd'hui, c'est super pratique
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

245

Pour les conventions de nommage, voici ce que j’aime bien :
CONSTANTE
NomDeType
nomDeVariable ou nom_de_variable
nomOperation
En C, quand une opération s’applique à un type de données précis ça me donne ça : void Type_operation(Type *this);

Et en ce qui concerne les variables globales, Zephyr a effectivement raison, ne diabolisons par leur usage. Cependant pour des raisons évidentes de lisibilité, maintenabilité et modularité c’est une très bonne chose de ne pas prendre l’habitude d’utiliser systématiquement des variables globales mais de réfléchir à ce qui a réellement besoin d’être global.
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. »

246

Sasume (./245) :
Et en ce qui concerne les variables globales, Zephyr a effectivement raison, ne diabolisons par leur usage. Cependant pour des raisons évidentes de lisibilité, maintenabilité et modularité c'est une très bonne chose de ne pas prendre l'habitude d'utiliser systématiquement des variables globales mais de réfléchir à ce qui a réellement besoin d'être global.

epee
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

247

Kevin Kofler (./235) :
Un code qui mélange toutes les variables dans une structure globale, c'est un code de porcs

Ma structure est locale à main, je passe juste un pointeur. Et du code de porc, que veux-tu, je début. Je vais pas m'amuser à faire 10 structures redondantes pour passer le pointeur de celle kivabien à telle ou telle fonction. C'est là que j'arriverais aux problèmes.
Ce que je fais, c'est la même chose qu'en assembleur, et c'est le plus efficace en vitesse sans relogement. smile
Sasume (./245) :
CONSTANTE
NomDeType
nomDeVariable ou nom_de_variable nomOperatio

Che moi,
CONSTANTE
nomdetype (comme les types built-in en fait)
NomVariable (var globale, ou var tirée de ma structure générale)
varlocale

Et merci pour vos explications sur les pointeurs. smile

248

Vous précisez toujour "return" à la fin de vos fonctions ?

Et écrivez-vous fonction(arg1, arg2)
ou fonction (arg1, arg2) ? (avec un espace avant la parenthèse)

Quand vous faites des opérations mathématiques, mettez-vous un espace entre les opérateurs et les variables/constantes ?

249

C'est pas utile ^^
Préciser return à la fin de tes fonctions, c'est comme préciser continue à la fin de tes boucles: sans intérêt grin
(Sauf si il y a une valeur de retour, cela va de soi)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

250

Folco (./248) :
Quand vous faites des opérations mathématiques, mettez-vous un espace entre les opérateurs et les variables/constantes ?

Oui
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

251

Godzil (./241) :
Il me semble que tu peux pas faire un

void*malloc(size_t size);


char *blabla = malloc(1024);
sans au moins te prendre un warning...

Si, et c'est exactement pour ça que le C permet de convertir un void * en n'importe quoi implicitement. (Le C++ introduit l'opérateur new pour ça.)
Folco (./247) :
Ma structure est locale à main, je passe juste un pointeur. Et du code de porc, que veux-tu, je début. Je vais pas m'amuser à faire 10 structures redondantes pour passer le pointeur de celle kivabien à telle ou telle fonction. C'est là que j'arriverais aux problèmes.

L'idée, c'est de ne pas avoir de structure du tout (sauf pour les trucs comme SCR_RECT qui vont vraiment ensemble, évidemment), mais de passer les paramètres un par un. Regarde un peu les prototypes des ROM_CALLs: dans la plupart des cas, ce n'est pas void fonction(STRUCTURE_ENORME*);, mais quelque chose de type int fonction(int a, int b, SCR_RECT *c, int d);. Le deuxième prototype fait nettement plus "C".
Ce que je fais, c'est la même chose qu'en assembleur

C'est bien ça le problème, il faut prendre des habitudes plus "haut niveau" pour écrire du C maintenable.
Folco (./248) :
Vous précisez toujour "return" à la fin de vos fonctions ?

Non! C'est idiot de mettre return; à la fin d'une fonction void, je n'ai vu personne faire ça.
Et écrivez-vous fonction(arg1, arg2)ou fonction (arg1, arg2) ? (avec un espace avant la parenthèse)

Là c'est plus débattu, mais personnellement j'ai horreur de cette espace inutile, ça cache l'appel de fonction, donc non, je ne la mets pas!
Quand vous faites des opérations mathématiques, mettez-vous un espace entre les opérateurs et les variables/constantes ?

En général non, la coloration syntaxique sert à ça, mais la plupart des personnes mettent des espaces autour des opérateurs.
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é

252

Euh il n'y a pas vraiment de conventions universellement adoptées et tout le monde va avoir des avis différents...

perso j'aime pas mettre des majuscules où que ce soit en C sauf dans les macros, ça me semble correspondre grosso modo aux conventions de la lib standard (oui bon ok FILE n'est pas une macro et NULL non plus, donc pas vraiment, mais bon je crois pas qu'il y ait une convention claire utilisée de façon constante dans toute la lib standard... enfin il me semble que tout est soit totalement en minuscule soit en allcaps, ils ne mélangent pas trop les deux)

quand j'ai des noms de variables ou fonctions (ou types...) en plusieurs mots je sépare par _, je déteste la conventionConsistantÀMettreDesMajusculesPartout c'est vraiment trop chiant à taper (en plus d'être moins lisible àmha), donc je ne l'utilise qu'en java (où c'est LA convention)
par contre nomdetypetrèstrèslongavectoutcollé ne me semble pas très lisible tongue

j'aime bien mettre des espaces presque partout, je trouve ça globalement plus lisible ; quelques exceptions : à l'intérieur des parenthèses, devant une virgule ou un point-virgule, après un opérateur unaire tel que * ou & ou !
donc j'écris genre fonction (3 * x + 250, -5);

Mais bon je suis pas très strict à ce sujet. Les seules espaces que je considère vraiment comme indispensables sont celles de part et d'autre du signe = et celles après une ponctuation (, ou ;) (à moins qu'il y ait un autre cas auquel je pense pas ^^)
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#

253

Kevin Kofler (./251) :
L'idée, c'est de ne pas avoir de structure du tout (sauf pour les trucs comme SCR_RECT qui vont vraiment ensemble, évidemment), mais de passer les paramètres un par un. Regarde un peu les prototypes des ROM_CALLs: dans la plupart des cas, ce n'est pas void fonction(STRUCTURE_ENORME*);, mais quelque chose de type int fonction(int a, int b, SCR_RECT *c, int d);. Le deuxième prototype fait nettement plus "C".

Je comprends bien, mais l'emmerdement c'est ça :
A appelle B, qui appelle C, et qui appellera peut-être C, D, E.

Alors bonsoir toute la fournée de variables que doit fournir A à B qui passera à C, peut-être aussi à C, D, E. Va falloir gérer tout ça inutilement dans la majorité des cas.
En plus, ça fait retourner juste une valeur, qu'il va falloir traiter. Si on doit agir sur 3 variables en conséquences, il y a tout un traitement à faire en retour de fonction, bonjour l'efficacité.

C'est peut-être pour ça que AMS pédale autant d'ailleurs grin

254

Si tu as toute une "fournée" de variables passée d'une fonction à l'autre sur plus de 3 niveaux, et qu'en plus tes fonctions "agissent" sur ces variables (c'est-à-dire modifient couramment des variables qui "appartiennent" à une autre fonction), c'est qu'il y a quelque chose qui ne va pas dans l'organisation de ton code. 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é

255

Ça dépend ce qu'il code, je peux te dire que quand tu codes un interpréteur (seule chose que j'ai codée sur TI) tu peux t'attendre à ce genre de situation... mais la solution logique est d'utiliser des variables globales dans ce cas.

Le coup de la grosse structure au lieu des plein de variables globales individuelles n'est lui qu'un hack pour pouvoir optimiser en mettant l'adresse dans un registre, mais c'est un truc qui se fait bien après coup avec des macros, le code est plus lisible (et plus facile à modifier : je peux toujours désactiver/modifier mes macros) si toutes les variables sont distinctes.
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#

256

Tu parles de ça en macro ?
#define Data->truc truc ?

257

Pour être tout à fait précis je parle de ceci (rajouté APRÈS COUP dans mon .h principal, le code étant déjà fonctionnel sans toutes ces définitions) :
typedef struct {
  word        *stack;
  byte        *prog_block_ptr;
  word        *stack_var_ptr; /* Ça c'est le « frame pointer » */
  word        pc_page;
  print_buf_t *pbf_p;

  char        *ti_location;
  char        *ti_status;
  
  pg_table_t   *pg_table;
  byte         *pg_start;
  
  word         pg_count;
  word         cur_page;
  word         MRU_pg_p;
  
  word font_style;
  int ligne_courante; 
  int position_x;
  
  /* Deuxième fenêtre (upper window) */
  
  Bool upper_win_active;
  word pos_x_upper_win;
  word pos_y_upper_win;
  word taille_up_win;
  
  /* print.c */
  print_buf_t text, room, stream3;
  Bool stream3_active;
  Bool output_disabled;
  
} structure_magique_t;

register word *stack_base asm ("a4");
register byte *base_ptr asm ("a3");
register long pc_offset asm ("d7");

#define structure_magique ((structure_magique_t*)stack_base)
#define stack (structure_magique->stack)
#define prog_block_ptr (structure_magique->prog_block_ptr)
#define stack_var_ptr (structure_magique->stack_var_ptr) /* Ça c'est le « frame pointer » */
#define pc_page (structure_magique->pc_page)
#define ti_location (structure_magique->ti_location)
#define ti_status (structure_magique->ti_status)
#define pbf_p (structure_magique->pbf_p)

#define pg_table (structure_magique->pg_table)
#define pg_start (structure_magique->pg_start)
#define pg_count (structure_magique->pg_count)
#define cur_page (structure_magique->cur_page)
#define MRU_pg_p (structure_magique->MRU_pg_p)

#define font_style (structure_magique->font_style)
#define ligne_courante (structure_magique->ligne_courante) 
#define position_x (structure_magique->position_x)

/* Deuxième fenêtre (upper window) */
#define upper_win_active (structure_magique->upper_win_active)
#define pos_x_upper_win (structure_magique->pos_x_upper_win)
#define pos_y_upper_win (structure_magique->pos_y_upper_win)
#define taille_up_win (structure_magique->taille_up_win)

  /* print.c */
#define text (structure_magique->text)
#define room (structure_magique->room)
#define stream3 (structure_magique->stream3)
#define stream3_active (structure_magique->stream3_active)
#define output_disabled (structure_magique->output_disabled)
Bon et en plus des macros ça a nécessité quand même une toute petite modification au _main ^^ (ajout des trucs en vert) :
stack_base = malloc(STACK_SIZE + sizeof (structure_magique_t));
if (!stack_base) {
ST_helpMsg (FRENCH ? "pas assez de mémoire" : "not enough memory");
return;
}
stack_base += STACK_SIZE / 2;
memset (stack_base, 0, sizeof (structure_magique_t));
(et bien sûr la suppression des déclarations de variables globales ^^)
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#

258

Kevin, vu que je ne comprends pas la manière dont d'après toi, il faut s'y prendre pour faire nettement plus C, voici le cas dans lequel je suis. C'est un éditeur de map pour mon moteur.

Ma structure :
{
// Global data
  SCR_RECT Clip;

// Sprites data
  SPRITE_16* SprTable;
  HANDLE SprHd;
  unsigned short SprLock;

// Map Data
  BOOL OpenedMap;
  unsigned char MapName[22];
  unsigned short MapWidth;
  unsigned short MapHeight;
  unsigned short Gravity;
  signed short Wind;
  unsigned char* MapPtr;
  unsigned char* MapDataPtr;

// Genlib Data
  BOOL OpenedGL;
  DSCREEN* DscPtr[2];
  HANDLE DscHd[2];
  unsigned short Tempo;
  PLANE* PlanePtr;
  unsigned short PlaneXS;
  unsigned short PlaneYS;

} DATA;

J'ai une fonction NewMap() qui se charge de renseigner les différents éléments de la nouvelle map (MapWidth, MapHeight, Gravity, Wind, MapName, PlaneXS, PlaneYS), et qui crée les handles de tiles et de données (MapPtr et MapDataPtr). Elle appelle une fonction qui lui dessine les différentes boites de dialogue, qui ont besoin de Clip. D'autres fonctions ont ausis besoin de Clip.
La fonction Configure() a aussi besoin de toutes les variables qui concernent la map.
Je n'ai aucune envie que chaque fonction doive définir le (SCR_RECT) Clip. Elles se servent donc toutes du pointeur dans la structure pour y accéder.

Alors comment faire pour appeler ma fonction NewMap(), lui faire renvoyer un seul résultat, et obtenir en retour les valeurs de MapWidth, MapHeight, Gravity, Wind, MapName, MapPtr, MapDataPtr, PlaneXS et PlaneYS ?

Une fonction qui initialise Genlib a besoin de PlaneXS, PlaneYS, MapWidth, et des autres variables spécifiques à Genlib.

Encore une fois, comment faire ?

259

tChez * moi
    (
    int    inOn,
    char * outFait
    )
    {
    int x    = comme(inOn);
    *outFait = ça();
    return NULL;
    }


sick

260

Y'a aucun problème dans ce que tu fais Folco...C'est peut-être un peu trop "objet" pour du C, mais ça s'arrête là.
Sinon pour les valeurs de retour multiple, c'est de bêtes pointeurs dans l'appel de fonction, et y'a aucune autre solution.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

261

Ah,quelque chose de réconfortant, merci grin
GoldenCrystal (./260) :
Sinon pour les valeurs de retour multiple, c'est de bêtes pointeurs dans l'appel de fonction, et y'a aucune autre solution.

Ben c'est ce que je fais, je passe le pointeur d'une structure. ^^
Mais j'aimerais savoir quel solution Kevin aurait employé dans mon cas précis.

262

De toute façon, c'est vraiment idiot de se forcer à pondre un code plus chiant juste pour ne pas utiliser les variables globales. Si ça te simplifie la vie, tant mieux top
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

263

Mais ce ne sont pas des variables globales, la structure est locale à main() => pas de relocs hehe

264

fatigue
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

265

C'est pas bien ? Ca change quoi d'avoir ce bloc global ou local à main ? confus

266

Quand c'est bien fait, l'utilisation d'une variable globale indexée par un registre, ou de -freg-relative-an, ne crée pas de relocations non plus wink
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

267

Très bien, mais quel avantage à avoir ça en global ? Ca m'éviterais de me ballader avec un pointeur partout ?

Euh attends, sans ton switch, ça reivent à l'utilisation normales de plein de variables globales ?

268

En fait, le problème des variables globales/statiques c'est essentiellement que ça empêche la réentrance de ton code.
Typiquement, tu ne peux pas appeler plusieurs bouts de code "en même temps" si ils utilisent la même variable, et que au moins l'un d'entre eux le fait en écriture. (Enfin si tu sais que ça peut arriver tu peux aussi prendre des précautions pour que ça ne cause pas de bug (cas du multitâches) mais c'est l'idée générale)
Par "en même temps", j'entend que un bout de code va s'éxécuter alors que l'autre n'a pas fini son éxécution. Donc ça affecte principalement, la récursivité, le multitâche (sur TI osef), et les instances multiples d'objets (pour les langages objets, ou dans certains cas similaires en C avec des structures).
Si ta variable ne va pas affecter la réentrance (cf. au dessus), tu peux clairement et sans aucun remords la définir en tant que variable globale. (Avec des langages objets c'est sensiblement plus rare qu'en C ^^)
Par exemple, le PID de ton processus sur Unix ou Windows, c'est une propriété globale du programme, que n'importe quelle fonction peut vouloir connaître, et tu peux clairement te permettre de le définir globalement dans ton programme.

Dans ton cas, apparemment, tu pourrais aussi utiliser une variable globale, en supposant que tu ne voudras/n'aura jamais à travailler sur plusieurs maps à la fois. Et c'est à peu près ce qu'il faut comprendre.

Les variables globales c'est pas le mal, mais c'est très souvent le mal. Quand ce n'est pas le mal alors c'est le bien et tu te dois (quasiment) de les utiliser.
(Et oui entre autres parce que ça va t'éviter de trimballer un pointeur/une valeur partout ^^)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

269

./267 > cf. ./232 , je pense que ça évite des restaurations de registres inutiles (mais je suis pas sûr)
Sinon d'un point de vue conception ça serait plus logique d'avoir quatre variables (clip, sprites data, map data et genlib data) mais les merger est probablement une optimisation (ou pas, ça dépend) puisque ça économise des registres.

Toujours d'un point de vue conception, il me semble que Clip certainement et GenlibData probablement pourraient logiquement être des variables globales tandis que MapData pourrait être une variable locale que tu passes, mais c'est vraiment sous réserve (je ne sais pas exactement ce que tu fais, donc c'est plus du feeling à partir de ce que tu as dit) et c'est pas forcément important.

Est-ce que Clip est vraiment une variable qui peut prendre plusieurs valeurs ? parce que sinon (si la valeur est fixe) ça devrait plutôt être une macro.
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#

270

Flanker: il veut pas de reloc car il veut faire du code flash XIP sous pedrom ^^


GC: la réentrance, sur TI, on en a un peu rien à péter si on fait pas de récursivité ^^
c'est pas comme si elle était multithread la bébête smile