Ok, donc l'endianness c'est bon à retenir pour les cas généraux, mais codant ti-only ici je m'en fous. Et les BMP c'est quoi ? Réellement une structure, pas un tableau ? J'ai jamais travaillé dessus en fait ^^ Même avec la SDL, il me suffisait de fournir un fichier en entrée, et la structure qui résultait de la création du sprite était opaque. "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Folco (./107) : Ce n'est pas ici ton problème, mais au moment de la définition. __attribute__((unused)) est une solution, mais évidemment GCC-only. Je pourrais aussi essayer de bidouiller le GCC de TIGCC pour qu'il accepte ça, mais ce ne serait pas une solution portable non plus. Pen^2 (./109) : Perso, j'utiliserais #define pour ça, ça donne du code beaucoup plus efficace (pas de pointeurs globaux à reloger). |
Kevin Kofler (./120) : A cause des relogements, c'est en effet ce que j'ai implémenté. Je me demande d'ailleurs pourquoi quand on a ça : .L0: .asciz "abcde" gcc s'empresse de rajouter : Str: .long #.L0 C'est bizarre, il y a toujours moyen de faire un lea/pea Str(pc) avec une chaine, pourquoi toujours créer une adresse absolue pour les chaines ? Kevin Kofler (./120) : Ben en fait, je ne peux pas définir les fonctions autrement, parce qu'elles sont appelées en tant que Callback par une lib qui ne connait que le proto "void (*func)(char)". Et quand la lib appelle une fonction, elle n'a aucun moyen de savoir que la fonction n'a pas besoin de ce foutu char ^^ "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Folco (./121) : Parce que c'est la sémantique de: const char * const x = "foo"; Utilise plutôt: const char x[] = "foo"; et le pointeur relogé aura disparu. Ben en fait, je ne peux pas définir les fonctions autrement, parce qu'elles sont appelées en tant que Callback par une lib qui ne connait que le proto "void (*func)(char)". Ce que je dis, c'est juste que c'est la définition le problème et pas la déclaration. Le code que tu as copié passe sans problèmes. |
Ah merci bien pour les deux tips. "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
L'en-tête des fichiers BMP est une structure. Si tu veux avoir une structure qui ne contient aucun padding (donc 100% telle que tu la déclares), il faut utiliser l'attribut "packed" dans la déclaration de ta stucture (c'est spécifique à GCC, il n'existe pas de façon standard de le faire en C). « Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau |
"MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Zerosquare (./124) : beaucoup de compilo supportent le pragma "pack" #pragma pack(1)
struct
{
}
#pragma pack() C'est apriori originaire de VisualC, mais GCC le support bien chez moi. Et je confirme: struct test_t {
int a;
char b;
int c;
};
struct test_t test = { 10, 20, 30};
struct test_packed_t {
int a;
char b;
int c;
} __attribute__((__packed__));
struct test_packed_t test_packed = { 10, 20, 30};
#pragma pack(1)
struct test_pragma_t {
int a;
char b;
int c;
};
#pragma pack()
struct test_pragma_t test_pragma = { 10, 20, 30};
gcc -S test.c -o test.s donne: .file "test.c" .globl test .data .align 4 .type test, @object .size test, 12 test: .long 10 .byte 20 .zero 3 .long 30 .globl test_packed .type test_packed, @object .size test_packed, 9 test_packed: .long 10 .byte 20 .long 30 .globl test_pragma .type test_pragma, @object .size test_pragma, 9 test_pragma: .long 10 .byte 20 .long 30 .ident "GCC: (Gentoo 4.4.3-r2 p1.2) 4.4.3" .section .note.GNU-stack,"",@progbits |
Intéressant, je ne savais pas qu'on pouvait l'utiliser sous GCC (dans la doc, ils disent qu'ils l'ont rajouté pour être compatible avec VC justement). Mais ça reste une extension... « Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau |
clang le supporte aussi. Edité par Godzil le 15-09-2010 à 16:12:37.[box=et meme mon gcc 4.2.2 pour ARM] .file "test.c" .global test .data .align 2 .type test, %object .size test, 12 test: .word 10 .byte 20 .space 3 .word 30 .global test_packed .type test_packed, %object .size test_packed, 9 test_packed: .4byte 10 .byte 20 .4byte 30 .global test_pragma .type test_pragma, %object .size test_pragma, 9 test_pragma: .4byte 10 .byte 20 .4byte 30 .ident "GCC: (GNU) 4.2.2"[/box] [box=et meme un gcc 3.4.1 pour arm] test_packed: .4byte 10 .byte 20 .4byte 30 .global test_pragma .align 2 .type test_pragma, %object .size test_pragma, 12 test_pragma: .word 10 .byte 20 .4byte 30[/box] Moralité, autant jeter les extention GNU non portable ^^ Squalyl: TG merci |
Et utiliser une extension VC non portable à la place? |
"moraliter" Nspire wiki CONDUCTEUR Va-et-vient Des QUATRE MANCHE AVEC DES DIODES |
Kevin Kofler (./129) : Les pragma sont un moyen standard de donner des ordres a un compilateur contrairement a des attributs comme le fait GCC. Si le compilateur ne comprend pas un pragma, il a deux possibilitée : - Il l'ignore - Il affiche un warning pour dire "ça je ne connais pas" Si tu utilise la méthode GCC, un compilo non GCC qui ne comprend pas va faire "Error - file.c:42: You put a fucking thing here that I don't understand" |
La sémantique du C originel n'est pas assez riche pour tout un tas de choses que l'on a rencontrées à l'usage, dans les programmes, par la suite... Et Comme les mécanismes d'extension sémantique du C n'ont pas été définis assez tôt (ou ne vont pas assez loin - #pragma est ancien mais ne va pas assez loin), c'est le bazar: #pragma incompatibles entre compilateurs, __attribute__, etc. Membre de la TI-Chess Team. Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP. |
(cross -> il dira f***ing Merci bien pour vos considérations ceci-dit, c'est intéressant. J'ai une question à propos des conventions d'appel : J'ai un programme P qui appelle une lib L en lui donant l'adresse d'une callback C Comment ça se passe au niveau des registres ? Est-ce que la callback attend que les registre a2-a6/d3-d7 aient les même valeurs qu'au moment où P a appelé la fonction de L ? Ou est-ce que L peut modifier ces registres à sa guise avant d'appeler C ? (du moment qu'elle les restaure avant le return vers P évidemment) En fait, je ne sais pas où chercher ces fonctions, je ne comprends même pas les expressions __attribute__((stkparm)) ou autres au niveau de la syntaxe C... "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Folco (./133) : C'est un appel de fonction comme un autre. Est-ce que la callback attend que les registre a2-a6/d3-d7 aient les même valeurs qu'au moment où P a appelé la fonction de L ? Non. Ou est-ce que L peut modifier ces registres à sa guise avant d'appeler C ? (du moment qu'elle les restaure avant le return vers P évidemment) Oui. En fait, je ne sais pas où chercher ces fonctions, je ne comprends même pas les expressions __attribute__((stkparm)) ou autres au niveau de la syntaxe C... __attribute__((stkparm)) veut dire que tous les paramètres sont passés par la pile, c'est la convention d'appel par défaut (mais généralement la moins efficace). Pour un callback, il est important d'utiliser une convention d'appel standard parce que la fonction L doit connaître la convention d'appel utilisée, c'est pour ça qu'on utilise généralement stkparm pour ça (cf. aussi la macro CALLBACK). |
Est-ce que la callback attend que les registre a2-a6/d3-d7 aient les même valeurs qu'au moment où P a appelé la fonction de L ? Complément au "Non" de Kevin: dans les callbacks, il faut donc prendre soin de réinitialiser les variables globales dans les registres ou le registre utilisé comme base pour les lectures, écritures et transferts de contrôle (forme de variable globale dans les registres). Membre de la TI-Chess Team. Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP. |
Complément au complément … sauf si la bibliothèque est en connaissance de la variable globale en question (par exemple, la fonction qsort de TIGCC réserve %a5, utilisé pour OPTIMIZE_ROM_CALLS). Mais par exemple AMS n'est en connaissance de rien. |
Kevin Kofler (./134) : Il n'y a aucun souci à spécifier qu'on passe les paramètres par registre ? Ca ne pose pas de problème ? C'est ce qui se fait pour les libs en général ? Y a-t-il des contre-indications ? Kevin Kofler (./134) : Et pourquoi ? Si j'écris une fonction de lib qui a ce proto : void libfunc (void (*callback) (char a = %d0, int b = %d1, short* c = %a0)) (à la syntaxe près évidemment) Le programme P appellera L en fournissant l'adresse d'une callback qui aura le même proto, non ? Alors en quoi serait-ce gênant ? Merci pour tes réponses, déjà. Lionel, je ne comprends pas "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
huhuhu |
Folco (./137) : Techniquement, il n'y a aucun souci. C'est juste que l'utilisateur devra déclarer sa fonction avec le même prototype, donc ça pourrait compliquer l'utilisation de ta bibliothèque. C'est plus simple pour l'utilisateur s'il doit juste mettre CALLBACK pour avoir la bonne convention d'appel (et s'il n'utilise pas -mregparm, même pas ça). |
Ok, merci bien. Je vais rester sur la solution simple alors. Zerosquare (./138) : Euh... mon fils utilise déjà les callbacks avec passage d'arguments... euh... par registre... tu crois que c'est grave ? "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Il a quel âge, déjà ? « Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau |
4 ans dans 2 mois. Mais je déconne, on a pas encore attaqué le callbacks "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Est-ce que ce prototype est correct, pour une fonction d'une lib asm appelable en C ? Edité par Folco le 20-09-2010 à 17:53:18.int pdtlib__CheckFileType(const char* Filename asm("a0"), unsigned char Type asm("d0"), const char* CustomType asm("a1")); Ai-je besoin d'écrire des __attribute__x quelque part, ou des __ATTR_LIB_x__ ? "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
La plupart des fonctions d'ExtGraph ont des prototypes avec des registres explicites tout à fait similaires à celui-ci, sans attributes. Si tu n'as pas d'autres souhaits spéciaux pour cette fonction (du genre, demander à GCC de vérifier les arguments avec des attributes GCC comme nonnull et format), pas besoin d'attributes. Membre de la TI-Chess Team. Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP. |
Ah ok, merci. On va dire que je ne domine pas le domaines des attribute "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
Si tous tes arguments ont une spécification de registre explicite, tu n'as pas besoin d'autres attributs, les attributs stkparm et regparm ne concernent que les arguments où le registre n'est pas spécifié explicitement. |
Parfait, merci. "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |
1. C'est génant si on passe une partie des arguments par registres, une autre par la pile (obligé, avec une va_list) ? Il suffit de ne préciser des registres que là où on en utilise et ça va ? 2. C'est gênant si on utilise des registres >= a2 ? "MSVC, le soft qui arrive à générer des problèmes à partir de solutions" © |