1470

Ok, merci.

1471

Je viens de percuter un truc :
man malloc ->
malloc()  alloue size octets, et renvoie un pointeur sur la mémoire allouée. Le contenu de la zone de mémoire n’est pas initialisé. Si
       size est nulle, malloc renvoie soit NULL ou un unique pointeur qui pourra être passé ultérieurement à free() avec succès.

Et si je tourne sur une implémentation où les char font 16 bits ? Si je veux un buffer de 20 caractères, je vais faire un débordement sans rien voir, non ?

1472

sizeof c'est fait pour les chiens ? embarrassed
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

1473

what what what what what what what what what what
Folco a lu "seize" à la place de "size" ??

1474

Une plateforme civilisée n'aura pas un char de plus de 8 bits! (Quant à moins de 8 bits, c'est carrément interdit par le standard.)
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é

1475

Ok. En fait, je suis en train de spécifier le fichier des highscores (simple, pour bosser une première fois avec les fonctions f*). Je me rends compte que pour qu'un tel fichier puisse être lisible en 32 et 64 bits, faut utiliser les définitions de stdint.h. Et bien utiliser des sizeof et compagnies (encore que sur les sizeof(uint*) doivent être constants quelque soient les implémentations justement).
Jyaif (./1473) :
Folco a lu "seize" à la place de "size" ??

Ah je viens de comprendre tellement c'est farfelu grin Non non, rassute-toi, et sinon je mets déjà des sizeof quand il en faut, entre autre pour la taille des structures, qui varie certainement en 32 ou 64 bits. Ce que j'ai fait tourne sans bugs sur les deux, c'est bon signe. smile

1476

./1471 : Il y a quelques rares exceptions, mais ce sont des processeurs sur lesquels ton programme n'aura aucune chance de tourner, de toute façon.
Si tu commences à vouloir gérer ce genre de cas, t'as pas fini. Te prends pas la tête avec ce genre de trucs.
Folco (./1475) :
encore que sur les sizeof(uint*) doivent être constants quelque soient les implémentations justement
Non. Ne fais pas de suppositions sur la taille des pointeurs. Pareil pour l'endianness.
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

1477

Merde, c'était le wildcard '*', je pensais à uint8, uint16, uint32 etc grin Ok, c'était pas clair ^^

Et sinon ok, je ne savais pas que c'était si rare. Je tiens juste à être compatible en 32 et 64 bits pour mon programme (sources, donc juste une recompilation), et j'aimerais que mes fichiers de données soient valables sur les deux plateformes (donc j'ai mis le nez dans stdint.h).

1478

Attention quand-même, il y a pas mal de programmes qui tenaient juste à être compatibles en 16 et 32 bits, et bah, sur une plateforme 64 bits, ils sont tous dans la m*rde. gni
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é

1479

Mais si j'utilise des sizeof(struct truc) dès que je parle de taille, il ne devraient pas y avoir de problème, non ? A moins qu'ils ne ramènent les int à 1 octet, là ok. grin

1480

m*rde

Par contre, les pointeurs sur des types m, je connais pas. embarrassed

1481

./1479 > Y'a aussi de sombres histoires d'alignement des données.
Mais faut juste savoir se rendre compte quand le problème vient de là (ça peut être difficile parfois, je l'admet), en général pas la peine de s'en préoccuper.
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

1482

GoldenCrystal (./1472) :
sizeof c'est fait pour les chiens ? redface.gif
Mais sizeof(char), ça fait toujours 1 wink Et bien sûr, l'allocation se fait en nombre de char et non d'octets... Donc pas de problème de débordement smile
avatar

1483

Ok. Ne comprenant rien à ces trucs de charset, je me méfie des caractères qui vont s'installer tranquillement sur deux octets sans me prévenir ^^

1484

Aaahh, tu confonds les charsets, et le type char. Je comprends enfin la question du ./1471 ...

1/le type char fera toujours 1 octet.
2/les charsets, ce n'est qu'un encodage. Tu connais l'encodage ASCII, ou une lettre est toujours codée avec 1 octets (= 1 char). Et bien il y en a d'autres encodages où les lettres sont codées avec plusieurs octets. Ça permet d'avoir un plus grand nombre de lettres différentes (en ASCII on a que 255 lettres différentes). Il y a des encodages où les lettres sont codées sur un nombre variable d'octets, comme l'UTF-8.

Bon, honnêtement c'est chiant de gérer autre chose que l'ASCII en C/C++, et quasi-personne ne le fait. Donc te connaissant, maintenant le premier truc sur ta TODO c'est de supporter l'UTF-8 dans ton programme, non?

1485

Jyaif (./1484) :
Bon, honnêtement c'est chiant de gérer autre chose que l'ASCII en C/C++, et quasi-personne ne le fait.
Euuuh... tu déconnes, là ? Énormément de logiciels le font, ne serait-ce que pour les traductions, ou pour utiliser les fonctions Windows qui sont en Unicode par défaut. Sous Linux je sais pas trop, mais j'imagine que ça doit être pareil.
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

1486

./1484 1/ C'est faux. Un char fait toujours un char, mais par forcement un octet. sizeof retourne la taille en nombre de char donc renvoie toujours 1 pour sizeof(char).
malloc prend en entrée une taille en nombre de char. La confusion entre les deux, comme dans la plupart des documentations (./1471 par exemple) vient de la mauvaise traduction de byte en octet. Un char correspond à un byte, mais pas forcément à un octet. Un byte est un groupe d'un certain nombre de bits qui peut être différent de 8, sa traduction en octet est souvent une erreur. Le mot octet existe aussi en anglais...

Folco, si tu veux utiliser des codages sur plusieurs octets par caractère, tu peux prendre un codage à taille fixe (UTF-32 par exemple) ou à taille variable (UTF-8), mais dans ce cas, il te sera impossible de déduire la taille en mémoire de la chaine uniquement à partir de son nombre de caractères.
avatar

1487

Thepro (./1486) :
./1484 1/ C'est faux. Un char fait toujours un char, mais par forcement un octet. sizeof retourne la taille en nombre de char donc renvoie toujours 1 pour sizeof(char).
malloc prend en entrée une taille en nombre de char. La confusion entre les deux, comme dans la plupart des documentations (./1471 par exemple) vient de la mauvaise traduction de byte en octet. Un char correspond à un byte, mais pas forcément à un octet. Un byte et un groupe d'un certain nombre de bits qui peut être différent de 8, sa traduction en octet est souvent une erreur. Le mot octet existe aussi en anglais...

Je connais toute cette merde théorique, moi je parle de la pratique.

1488

Merci pour tout. smile


Pour changer, j'ai un warning àlakhon, et je ne sais pas ce que GCC veut dire. Ce qui m'emmerde, c'est que je dois faire qqchose de travers... sans m'en rendre compte.
J'ai ces déclarations :
module.h:

struct CUSTOM_DATA;

typedef struct
{
    SDL_Surface* background;
    SDL_Rect bgPosition;
    int numIcons;
    ICON* iconList;
    struct CUSTOM_DATA* customData;
} MODULE_DATA;

careers.h, inclus après module.h:

typedef struct
{
    uint16_t numEntries;
    ENTRY_CAREER* careersPtr;
} CUSTOM_DATA;

Et dans mon code, je fais ceci :
    uint16_t numberEntries = 0;
    MODULE_DATA* data;
    data = malloc (sizeof(MODULE_DATA));
    [...]
    data->customData = malloc (sizeof(uint16_t) + sizeof(ENTRY_CAREER*));
    data->customData->numEntries = numberEntries;

Et là, j'ai un dereferencing pointer to incomplete type à la dernière ligne...
Pourquoi ? Qu'est-ce que ça veut dire, déjà, un "type incomplet" ?
Ensuite, quand je caste (ce que je pense être inutile) comme ça :
((CUSTOM_DATA*)data->customData)->numEntries = numberEntries;
Ca marche nickel.

Evidemment, je foire un truc, mais quoi ? Je respecte bien mes structures dans mes déréférencements, ma variable data est bien typée etc... Que pasa ?

1489

Ah, j'avais pas vu le spoiler grin
Jyaif (./1484) :
Donc te connaissant, maintenant le premier truc sur ta TODO c'est de supporter l'UTF-8 dans ton programme, non?

Non, au contraire, je ne prendrai que des caractères ascii en entrée grin

1490

c'est parce que tu mélanges l'utilisation du type struct CUSTOM_DATA et du typedef CUSTOM_DATA. les deux sont des types différents en C il me semble.
tu dois choisir d'utiliser l'un ou l'autre
avatar

1491

Type incomplet veut dire ce qu’il veut dire : gcc ne connaît pas complètement le type pointé que tu déréférences. Es-tu bien sûr d’inclure tous les .h qui définissent tes types ?
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. »

1492

Erf... j'arrive pas à m'en dépatouiller...

Je repars donc de ça :
struct CUSTOM_DATA;

typedef struct
{
    SDL_Surface* background;
    SDL_Rect bgPosition;
    int numIcons;
    ICON* iconList;
    struct CUSTOM_DATA* customData;
} MODULE_DATA;

MODULE_DATA est en fait une structure générique dont tous les membres sont utilisés par les MODULE :
typedef struct
{
    void (*unload)(MODULE_DATA* data);
    void (*manage)(MODULE_DATA* data);
    MODULE_DATA* data;
} MODULE;

Le CUSTOM_DATA* customData me permet en fait de dériver cette classe en fonction des modules (introduction, highscrores etc...) avec des données personnelles à chacune de ces classes.
Y a-t-il un problème à avoir alors un void* customData dans MODULE_DATA, que chaque MODULE va caster après en fonction de ce qu'il utilise pour ses propres besoins ?

En d'autres termes, suis-je toujours sûr d'avoir sizeof(void*) == sizeof(MODULE_TRUC_DATA*), MODULE_TRUC_DATA pointant sur une structure ou un simple buffer ?
Est-ce qu'un tel cast est toujours safe ?

Sasume : oui, j'ai ça dans le source incriminé, sachant qu'en fait, careers.h inclut déjà module.h :
#include    "module.h"
#include    "careers.h"

1493

oui, les pointeurs ont tous la même taille

tu veux dire que tu redéfinis plusieurs fois différemment la structure CUSTOM_DATA ? c'est crade et potentiellement un nid à emmerdes. utilises un void* que chaque module va caster différemment

et ne mélange pas CUSTOM_DATA* et struct CUSTOM_DATA*, c'est des types différents pour un compilo C
avatar

1494

Édit, j'avais mal lu...

Peut-être devrais-tu inclure les .h dans un autre ordre et enlever la ligne struct CUSTOM_DATA;.
avatar

1495

Ok, merci beaucoup pour tout.
aze (./1493) :
c'est crade et potentiellement un nid à emmerdes. utilises un void* que chaque module va caster différemment

Comme j'aime pas les casts systématiques (je trouve pas ça très propre d'y avoir recours à tout bout de champs), je comptais faire ça à coup de #indef #define #endif, mais je sais pas si c'est moins crade grin

1496

non, caste systématiquement. ou utilise du C++, de l'héritage et des virtuelles cheeky
avatar

1497

Utilise les possibilités d’héritage du C++ oui
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. »

1498

Sasume -> je suis en C, là grin

aze -> Oui, caster quand il le faut bien sûr, mais des casts dans tous les sens peuvent s'avérer être un problème de conception (j'utilise un int pour faire ça, alors que je sais très bien que les fonctions auxquelles je le passerai demande un short mais je m'en fous.

1499

Folco (./1480) :
m*rde

Par contre, les pointeurs sur des types m, je connais pas. embarrassed

C'est une multiplication. gni
Jyaif (./1484) :
Bon, honnêtement c'est chiant de gérer autre chose que l'ASCII en C/C++, et quasi-personne ne le fait.

Bah, l'UTF-8 est en général plus ou moins géré sans faire exprês. hehe Du moins si les libs d'affichage qu'on utilise le gèrent d'office.
Zerosquare (./1485) :
Euuuh... tu déconnes, là ? Énormément de logiciels le font, ne serait-ce que pour les traductions, ou pour utiliser les fonctions Windows qui sont en Unicode par défaut. Sous Linux je sais pas trop, mais j'imagine que ça doit être pareil.

Sous GNU/Linux, "tout est un surensemble d'ASCII" reste vrai même pour le Unicode système qui est de l'UTF-8. tongue Cf. aussi ma réponse à Jyaif. Certains frameworks portables comme Qt ou Java ont choisi l'UTF-16 comme leur représentation interne (et du coup là aussi, gérer l'UTF-8 devient presque trivial, il suffit de faire attention aux conversions char *QString), mais la représentation native de Unicode est l'UTF-8.
Folco (./1488) :
Pour changer, j'ai un warning àlakhon, et je ne sais pas ce que GCC veut dire. Ce qui m'emmerde, c'est que je dois faire qqchose de travers... sans m'en rendre compte.

Il faut changer:
typedef struct
{
    uint16_t numEntries;
    ENTRY_CAREER* careersPtr;
} CUSTOM_DATA;

en:
typedef struct CUSTOM_DATA
{
    uint16_t numEntries;
    ENTRY_CAREER* careersPtr;
} CUSTOM_DATA;

comme je t'ai déjà expliqué à un endroit que je ne retrouve plus.

Les solutions proposées par les autres ne sont que des bidouilles pour contourner le vrai problème et sa solution évidente.
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é

1500

il doit y avoir des meilleurs designs, oui. mais redéfinir le même nom de struct ne change rien au design qui utilise un cast de CUSTOM_DATA*. c'est juste une bidouille pour éviter d'écrire à chaque fois tes casts.

après, on parlait de casts de pointeurs, c'est pas vraiment la même problématique que les casts de nombres
avatar