1

yop,


J'ai un souci, je ne sais pas trop d'où ça vient. Mais au moins le test case est super simple :/* Déclaration anticipée */ struct truc_t; /* Première structure utilisant un pointeur vers la seconde */ typedef struct machin_s { void (*func) (truc_t* t); } machin_t; /* Définition de la structure déclarée auparavant */ typedef struct truc_s { int i; } truc_t; int main (void) { }
A la compilation, j'ai ce message :
main.c:12: error: expected ')' before '*' token
main.c:13: warning: no semicolon at end of struct or union
main.c:13: warning: struct has no members

Alors si je ne fais pas de déclaration anticipée, et déclare truc avant machin, ça marche.
Mais vous vous doutez bien que si présente les choses sous cette forme, c'est que les déclarations sont sous cetet forme dans les headers, et se présentent dans cet ordre-là.


Ce que je ne comprends pas, c'est d'où vient l'erreur. En effet, la déclaration partielle de struct truc devrait permettre au compilo de décrire correctement la structure machin, qui contient un pointeur de fonction, non ?
Pourquoi "ça veut pas" ? confus

2

Ton typedef arrive trop tard, il faut que tu inverses l'ordre de déclaration (sinon truc_t est déclaré comme struct, puis comme typedef d'une autre struct quelques lignes en dessous, d'où conflit).
/* Déclaration anticipée */ typedef struct truc_s truc_t; /* Première structure utilisant un pointeur vers la seconde */ typedef struct machin_s { void (*func) (truc_t* t); } machin_t; /* Définition de la structure déclarée auparavant */ struct truc_s { int i; }; int main (void) { }
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

Merci. Je pensais que c'était une histoire de pointeur de fonction encore une fois, car j'ai toujours des emmouises avec. Cool ! top

4

Suite. Je n'arrive pas à faire une affectation de structure. Voilà ce que j'ai :

Une structure Global qui contient un tableau de Module :struct Global { Module ModuleList [9]; };
La structure Module contient trois pointeurs de fonctions :typedef struct Module { Init_t Init; Manage_t Manage; Draw_t Draw; } Module;
Je voudrais affecter une structure Module à ModuleList [0] :global->ModuleList [0] = {InitIntro, ManageIntro, DrawIntro};
Mais ça ne compile pas :
main.c: In function '_main':
main.c:15: error: expected expression before '{' token

Donc deux solutions qui marchent :
- le cast :global->ModuleList [0] = (Module) {InitIntro, ManageIntro, DrawIntro};
- la variable intermédiaire :Module m = {InitIntro, ManageIntro, DrawIntro}; global->ModuleList [0] = m;

Les deux marchent. Le premier ne me plait guère, je peux caster {1} et ça marchera, donc il y a un risque d'erreur. Le second marche à merveille, mais est plus lourd en écriture.

1. Pourquoi ça ne pourrait pas marcher, ce que j'essaye ? La structure que je je veux affecter est bien du type attendu
2. Y a-t-il une solution plus élégante ou propre à ce que je veux faire ?

Merci d'avance.

5

La syntaxe que tu cherches à utiliser dans ta troisième balise [source] n'est valable qu'à la déclaration, pas à l'assignation. Il me semble que ta première solution qui marche est une extension de GCC, à vérifier (et si c'est le cas, poubelle direct © grin). Ta seconde fonctionne puisque c'est une déclaration.

Si tu veux quelque chose de strict au niveau du typage, et que tu es en C++ (je ne sais pas si tu fais du C ou du C++, tu n'as pas précisé) tu peux ajouter un constructeur à ta struct "Module" (au passage, ignoble le typedef qui a le même nom que la struct !) qui prend en paramètre tes trois pointeurs.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

6

Ah, merci bien. smile

D'accord avec toi pour l'extension GCC. Je n'aime pas les utiliser par principe, même si certaines sont sûrement très bien.
Je suis en C, donc pas de cnostructeur.

Et pour la structure qui a le nom de son type, "ça marche", et ça m'évite de comprendre trop de choses grin Je sais c'est dégueulasse et c'est pas dans mes habitudes, mais j'ai du mal à faire la distinction entre un nom de structure et son type... Je ne comprends pas pourquoi les deux ne sont pas liés...

7

Alors as-tu vraiment besoin de spécifier le nom de la struct ? Tu pourrais faire simplement ça : typedef struct { Init_t Init; Manage_t Manage; Draw_t Draw; } Module;
ça aura au moins le mérite de lever une ambiguïté smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

8

Ah en effet. Merci. smile


(et pourtant, chaque fois que je vais aux chiottes, j'ai mon bouquin de C à la main. quand je code, je le consulte aussi régulièrement. Je retourne cplusplus.com quand je fais du cpp, et je cherche toujours avant de demander. Mais j'ai vraiment du mal avec ces langages de lpus haut niveau que l'asm. Trop de concepts qe je maitrise pas, alors que j'ai pensé "instructions optimisées" et non "algo" pendant trop longtemps. Féchier, j'avance à rien, et je code pas assez pour avancer sad).

9

moi c'est l'inverse tripo
et la le mec il le pécho par le bras et il lui dit '

10

trisotfl

(mais bon, ya le Mickey Parade d'à côté qui t'a trahi, avoue tongue)

11

[nosmile]j'avoue, j'ai mis du temps à retrouver le bouquin grin
et la le mec il le pécho par le bras et il lui dit '

12

Folco (./6) :
mais j'ai du mal à faire la distinction entre un nom de structure et son type... Je ne comprends pas pourquoi les deux ne sont pas liés...

Pourquoi ne pas avoir imposé directement de définir un type quand on définit une structure, par exemple, plutôt que de nommer les structures ?
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

13

#K&R# grin
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

14

Oh ! Vous me rassurez grin

15

./12 : le simple fait que ça ait été "corrigé" (ajouté, en tout cas) en C++ répond à ta question, à mon avis ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

flanker (./12) :
Folco (./6) :
mais j'ai du mal à faire la distinction entre un nom de structure et son type... Je ne comprends pas pourquoi les deux ne sont pas liés...
Pourquoi ne pas avoir imposé directement de définir un type quand on définit une structure, par exemple, plutôt que de nommer les structures ?
C'est le cas, c'est juste que ces types (appelés "tags") ne sont pas dans le même namespace que les identifiants ordinaires. En fait [code]typedef[/code] n'a pas été pensé pour être utilisé systématiquement de la sorte. Normalement le code devrait ressembler à ça :/* Déclaration anticipée */ struct truc; /* Première structure utilisant un pointeur vers la seconde */ struct machin { void (*func) (struct truc *t); }; /* Définition de la structure déclarée auparavant */ struct truc { int i; }; int main (void) { }
Le code est plus simple, et ça apporte plusieurs avantages :

- c'est le style utilisé par la libc (struct tm, etc...), ainsi que POSIX (struct stat, etc...), du coup le code est plus homogène.

- comme il s'agit d'un namespace spécifique aux structs, unions et enums, on n'a plus besoin de rajouter un préfix ou un suffix ("_t"). Il est possible d'utiliser [code]struct truc truc;[/code] pour déclarer une variable "truc" du type "structure truc". Je précise en passant que le suffix "_t" est réservé par POSIX dès lors qu'on inclue un header système, l'utilisateur n'est pas censé l'utiliser pour ses types personnels, sous peine d'incompatibilité avec les futures versions du compilateur.

- en lisant du code qui déclare des variables ou des paramètres struct, on connaît directement la sémantique des opérations effectuées sans avoir besoin de chercher la déclaration du type. Autrement dit, lorsqu'on voit [code]struct truc a, b; a = b;[/code] on sait que l'affectation copie la structure de données, avec [code]truc_t a, b; a = b;[/code] on ne sait rien, ça peut être un pointeur, un int, ou autre, on ne connaît pas le coût de l'opération à priori, ni même sa sémantique. C'est un gros point faible du langage qui fait que [code]typedef[/code] n'est pas vraiment utilisable (et n'a pas été conçu) pour faire de l'encapsulation proprement.

- en C++ la gestion des tags est différente, comme l'a précisé Zeph, il n'est pas nécessaire de mettre [code]struct/class/union/enum[/code] devant chaque tag.

So much code to write, so little time.

17

Zeph (./15) :
./12 : le simple fait que ça ait été "corrigé" (ajouté, en tout cas) en C++ répond à ta question, à mon avis ^^

Ça me fait penser à une autre question : est-ce qu'il y a beaucoup de choses empêchant de compiler un code C par un compilateur C++ ?
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

18

avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

19

Ah tiens, je n'avais pas vu la page wikipedia... Bon, ça devrait être bon alors happy Merci ^^
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

20

Je me rappelle avoir fait un code C à la con pour montrer ça.
On y voit:
* Utilisation de mots réservés du C++
* Utilisation de nom de structure comme nom de variable (en gros, une conséquence du comportement observé dans ce thread)
* Cast implicite de void* en XXX*

En gros, il y a un subset commun qui est assez grand, mais pas égal à C.
Aussi, la dernière fois que j'ai parcouru le standard C++, il ne disait pas que CHAR_BIT devait être >= 8 (ce qui est le cas du standard C).

Dans l'autre sens, un truc que je reproche au C est qu'il n'aime pas (lire:Il met une erreur ou au moins un warning) convertir int** en int const* const*, ce qui est parfaitement légal en C++ (notez qu'il faut les deux niveaux de const).
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

21

T'es une pointure sur developpez.net, toi cheeky

22

Plus trop en ce moment, je traîne moins sur les forums maintenant.
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.