[C] Petit problème de déclaration de structure

Salut à tous!

J’ai un petit problème concernant la déclaration d’une structure.

Je joint ci-dessous une archive contenant un programme (qui ne sert à rien du tout!) qui illustre parfaitement et de manière très simplifiée mon problème:
http://bluelambda.free.fr/test.tar.gz

Il y a donc 4 fichiers:

  • test.h, qui contient une déclaration de fonction de test.c, et une déclaration du type d’une structure
  • test.c, qui contient la fonction déclarée dans le .h, et la déclaration de la structure
  • main.c, qui exploite le fichier test.h, ici je tente d’utiliser une structure du type déclaré dans test.h
  • Makefile, qui permet de compiler le tout

Il est préférable que vous regardiez les fichiers, qui font chacun une dizaine de lignes, et qui vous aideront à bien voir de quoi il s’agit.

Lorsque je compile, j’obtiens les erreurs suivantes:

gcc -g -Wall -W -c main.c main.c: Dans la fonction «main» : main.c:8: erreur: invalid application of «sizeof» to incomplete type «struct ma_structure» main.c:10: erreur: déréférencement d'un pointeur de type incomplet main.c:11: erreur: déréférencement d'un pointeur de type incomplet make: *** [main.o] Erreur 1

D’après ce que je comprends, la déclaration de la structure présente dans test.c n’est pas accessible dans les fonctions de main.c. Il ne connaît pas les champs contenus dans la structure, donc me sort une erreur.

Je pense que le problème vient du Makefile, je débute dans la création de ces fichiers, je n’ai peut être donc pas bien compris quelque chose, et il doit y avoir des problèmes de dépendances.

Quelqu’un ici aurait-il l’aimabilité de m’éclairer? Je bloque un peu là B)

PS: je ne veux pas avoir à déclarer ma structure dans le .h. On devrait pouvoir s’en sortir en déclarant seulement le type dans le .h non?

ta structure tu la définis directement dans le .h, comme s’il s’agissait d’une variable.

pas nécessaire de faire de calloc pour une structure.

pour accéder à une structure, vu que ce n’est pas un pointeur vers une structure, tu utilise un point.

lorsque tu fais des allocations dynamique de mémoire, il faut prévoir de la libérer (free). sizeof s’utilise comme cela :

sizeof(ma_structure)

il faudra prévoir une allocation de mémoire pour utiliser ton pointeur vers char de ta structure.

test.c

[code]#include “test.h”

// fonction de test
void fct_test()
{
ma_structure s;

s.i = 10;
printf("%d\n", s.i);

}[/code]

test.h

[code]#ifndef TEST_H
#define TEST_H

#include <stdio.h>
#include <stdlib.h>

// je definis mon type
typedef struct {
int i;
} ma_structure;

// petite fonction pour tester le tout
void fct_test();

#endif[/code]

main.c

[code]#include “test.h”
#include <stdio.h>

int main()
{
ma_structure s;

s.i = 10;
printf("%d\n", s.i);

fct_test();

return 0;

}[/code]

ton code présente quand meme de grosses lacunes de base. il faudrait revoir quelques cours de C.

[quote=« bluelambda, post:1, topic: 31032 »]Salut à tous!

J’ai un petit problème concernant la déclaration d’une structure.[/quote]
Small? no no not a SMALL. A big one. A huge.
Does you who starting up something with libusb api? does it work? Man, come on.

And roll over the floor laughing with tears in your eyes.

[quote=« bluelambda, post:1, topic: 31032 »]Lorsque je compile, j’obtiens les erreurs suivantes:

gcc -g -Wall -W -c main.c main.c: Dans la fonction «main» : main.c:8: erreur: invalid application of «sizeof» to incomplete type «struct ma_structure» main.c:10: erreur: déréférencement d'un pointeur de type incomplet main.c:11: erreur: déréférencement d'un pointeur de type incomplet make: *** [main.o] Erreur 1[/quote]
sigh. You know what? You DON’T even know what a typedef is:

[code]struct ma_structure{
char *c;
int i;
};

// je definis mon type
typedef struct ma_structure * ma_structure;[/code]
So, what is the mistake here? huh? both struct and typedef have the same name. And this is BAD. You know that, wouldn’t you?

hoo that’s good. You are right. amazing.

No no, here you are wrong. damn’ wrong. The main problem is DAMN’ simplier.

Here I am. Happy?

No you can’t.

Can I do anything else for ya?

PS: je sais, j’ecris mal en anglais mais je voulais m’amuser un peu, et puis je viens de voir River of souls tout en anglais, j’ai du mal a reprendre le francais B)
edit:

La bonne parole. Thank you. Enfin moi je vois une struct et un typedef defini avec le meme nom, je me marre hein. Fallait pas lui faire son exo Maverick, il va plus rien avoir a faire.

LoneWolf
Des fois, blue, tu merites des baffes. B)

what a constructive réponse you did …
yes it was, but you more conote “I have the biggest” than anythinkg.
we could ask wether your aim is to help him or to prevent him to post again here.
what is a forum for, if that’s not to help each others ?

oops j’ai parlé anglais, c’est la folie de “I speak wall street english” …

[quote=“fser, post:4, topic: 31032”]what a constructive réponse you did …
yes it was, but you more conote “I have the biggest” than anythinkg.
we could ask wether your aim is to help him or to prevent him to post again here.
what is a forum for, if that’s not to help each others ?

oops j’ai parlé anglais, c’est la folie de “I speak wall street english” …[/quote]
Tu devrais y retourner, t’as du rater des cours.

Mouhaha desole mais j’ai pas pu m’empecher B)

LoneWolf
Taquinerie du soir (ouais il est plus que dodo time la)

Ah ben on dirait que toi aussi B)
non ce que je veux dire c’est que tu te rends pas compte de l’impact sur un petit coeur de messages aussi “francs” que le tient …
ça fait pas tres tres tres plaisir quoi.

Fser
se rappelle …

Mais non, c’est du Lony en forme, c’est tout.
Par exemple, lancez-le sur un article du ouèbe du genre “le SATA c’est tellement plus trop fort que le SCSI”, prenez un gobelet de pop-corn et voilà un bon moment à passer B)

Bon, j’ai réussi à m’en sortir, mon programme fonctionne.
Vous pouvez me donner vos avis ça me permettra de m’améliorer, cependant tenez compte qu’il reste des optimisations à faire mais que j’ai la flemme ce soir. Je pense notamment pouvoir réduire pas mal le nombre de variables à certains endroits.
Voyez par vous mêmes:
http://bluelambda.free.fr/annuaire.tar.gz

N’hésitez pas à me faire part de vos remarques.

Je vous remercie de vos réponses, et je vais répondre à vos remarques à présent.

Maverick

[quote]pour accéder à une structure, vu que ce n’est pas un pointeur vers une structure, tu utilise un point.[/quote]Justement, toutes mes structures je les utilise comme des pointeurs, c’est bien plus pratique je trouve, car je n’ai jamais besoin de me demander « Je travaille avec un pointeur ou pas là? ». Bref, je mets toujours un → et c’est réglé, et ça facilite les choses dans certains cas.
Pour avoir utilisé la méthode classique avec des « . » et des « -> » pendant un moment, je préfère largement la méthode pointeur only.
Après c’est peut être une question de goùts.

[quote]pas nécessaire de faire de calloc pour une structure.[/quote]Comme je l’ai dit, étant donné que toutes mes structures sont des pointeurs, je dois obligatoirement réserver la mémoire si je veux travailler dessus B)

[quote]lorsque tu fais des allocations dynamique de mémoire, il faut prévoir de la libérer (free).[/quote]Exact, j’utilise d’ailleurs cette fonction dans mon programme Annuaire ci dessus.

LoneWolf

[quote]Does you who starting up something with libusb api? does it work? Man, come on.[/quote]Oui, c’est bien moi qui travaille sur un projet utilisant libusb. Mais la présente question concerne un projet qui n’a rien avoir B)

[HORS SUJET]Mes soucis avec libusb viennent de quelque chose que j’ai mal compris sur la gestion de l’USB, il faut que je me replonge encore un peu dans de la doc.
Le firmware de ma carte gère mal l’USB quelque part, et certains OS n’apprécient pas, pourtant sous d’autres OS ça passe sans problèmes, donc ce doit probablement être un détail.
Peu importe, je refais le firmware de ma carte en entier actuellement, et après je referai mon programme pour l’utiliser avec libusb, l’ancienne version étant plutôt mal organisée (c’était la première et c’était mes débuts avec l’USB)
Si tu es intéressé par le projet c’est une interface MIDI USB universelle (c.a.d qui supporte toutes les normes MIDI de la création), tu en saura plus quand je publierai le tout sous une licence libre (c’est à dire quand ce sera utilisable, si j’estime que c’est utilisable un jour)[/HORS SUJET]

Non.
Ceci déclare une structure de type pointeur:

typedef struct ma_structure * ma_structure;

Et ceci déclare la structure qui correspond:

struct ma_structure{ char *c; int i; };
Et ensuite, si je veux déclarer une variable de type ma_structure, je fais un:

ma_structure variable;

Ce que tu dis aurait été vrai si je n’utilisais pas des structures pointeurs.

[quote]No no, here you are wrong. damn’ wrong. The main problem is DAMN’ simplier.[/quote]En effet, j’ajoute la déclaration de la structure dans le .h (voir le programme Annuaire que je viens de poster). Et ça marche.

Mon exo fonctionne, comme tu peux le voir, preuve que tu as critiqué ma (bonne) façon de faire :smiley:
Au fait, la prochaine fois que je réponds à un de tes posts, ce sera en espagnol :smiley:

ouais j’avais pas vraiment regardé ton code en détail.

sinon où était le problème ?

[quote=« bluelambda, post:8, topic: 31032 »]Mon exo fonctionne, comme tu peux le voir, preuve que tu as critiqué ma (bonne) façon de faire :smiley:
Au fait, la prochaine fois que je réponds à un de tes posts, ce sera en espagnol :D[/quote]
Bonne facon? Euh non. C’est pas parce que ca compile que c’est une bonne facon. Ca marche parce qu’il differencie « struct toto » et « toto » tout seul, mais niveau code, c’est juste immonde.
Deux entites DIFFERENTES avec le meme nom, c’est naze. On me fait ca en cours, je mets 0 direct (ou presque).

Sinon, pas de bleme pour l’espagnol, je le comprends pas donc je pourrais pas t’aider (meme si ma maniere est particuliere) alors qu’en tant que geek, j’imagine que tu comprends mon (mauvais) anglais.

Maverick: Le probleme etait la declaration de la structure dans un .c et pas dans le .h (et forcement, ca marche pas).

fser: Je fais ca a tout le monde et y en a que ca gene pas. Les questions ne seraient pas aussi stupides, je serais pas aussi mechant. (sinon ouais ma phrase est pas bonne mais j’ai prevenu que j’etais naze en anglais et pis merde si je peux plus m’amuser dans mes posts, ou va t on :P)

vectra: hehehe B)

LoneWolf
Persecuteur de fser et de bluelambda - les pov’ petites chatounes B)

(moi je préférais l’époque ou Lonewolf il était chomeur, au moins il donnait pas l’impression d’être un sale con prétentieux donneur de lecons)

Ouais mais c’est pas possible de rester tres longtemps au chomage hein… faut bien des sous pour acheter des bidules geeks B)

LoneWolf
Mais non j’ai pas change, j’suis toujours le meme chieur B)

Ce que tu semble ne pas comprendre c’est que:

(déclaration du type)
et

struct Fiche { char * nom; char * prenom; char * tel; };
(déclaration de la structure)
C’est la MEME chose. La même entité que je déclare. Donc en fait non, je n’utilise pas le même nom pour deux entités DIFFERENTES. Si c’était le cas ça ne marcherai pas en plus, gcc me sortirai au moins un beau Warning.

Et c’est comme ça qu’on déclare proprement une structure de type pointeur.

Après dans mon code en C si je eux une variable de type Fiche, je ferai:

Si tu as une autre solution, meilleure peut être, pour déclarer une structure de type pointeur, je suis tout ouïe.

Sigh. Et dire qu’on dit que je suis pretentieux. B)

Blue, pour la derniere fois, utilise ton cerveau et REFLECHIS.

Deja, 1, une structure et un typedef ne sont pas identiques a mon avis, mais bon, ca peut etre sujet a discussion, admettons. (ca reste une definition dans les deux cas, donc bon)

Mais toi, tu definis une structure PUIS un type “pointeur vers une structure”. Et non non, c’est CLAIREMENT pas la meme chose. D’ailleurs:

[code]#include “annuaire.h”

void main(void)
{
printf("%d, %d\n",sizeof(Fiche), sizeof(struct Fiche));
}[/code]
Resultat:
4, 12

genre c’est pareil.

Moi quand j’ai vu ca hier soir, j’ai rigole et j’ai fait ca:

// je definis mon type typedef struct ma_structure * pt_ma_structure;
La au moins, on sait ce que c’est. J’imagine qu’il y a meme plus propre comme denomination.

Enfin si apres ca t’as toujours pas compris, je peux plus rien pour toi.

LoneWolf
Martelons, martelons. B)

De toutes façons on a appris comme ça en cours, j’ai le polycop du TP sous les yeux et j’ai juste recopié les déclarations que le prof demandait pour les structures.
C’est mon prof qui note, donc je fais comme il demande B)

Pourquoi le même nom?
On notera que “struct Fiche” et “Fiche” ce n’est pas DU TOUT la même chose.

C’est un peu comme si tu me disais que:int variable; int ma_variable; c’est la même chose sous pretexte que “variable” est présent dans le deux cas (bon OK mon exemple est moche).

Le fait de rajouter “struct” devant “Fiche” fait que l’on change complètement d’objet, moi ça me choque pas tellement en fin de compte.

C’est un peu comme quand tu rajoutes “&” devant une variable en fait.

Il faut lire la ligne correctement:typedef "struct Fiche" * "Fiche";

Je me renseignerai lundi auprès de mes profs, mais je sais qu’ils vont me répondre que “struct Fiche” et “Fiche” c’est pas du tout pareil donc que ça ne pose aucun problème.

Lonewolf a raison, ce sont deux choses différentes, et leur donner le même nom n’est pas une bonne idée. Ceci dit, en C ça fonctionne parce que le compilo distingue “struct toto” et “toto”. Le jour où tu passera au C++ ça va plus fonctionner, car une structure est alors un type à part entière.

Concernant ton approche du “tout pointeur”, là aussi je pense que c’est pas une super idée. Tu te rendra vite compte que lorsque le contexte devient un peu plus complexe, on s’y perd vite, et les bugs dûs aux pointeurs sont bien 1/3 des plus fréquents. Vivent la stack et les références. Mais c’est effectivement le genre de choses qui viennent avec la pratique, y’a pas de mal à faire ses propres expériences.

C’est en programmant qu’on devient programmeur. Bidouille, amuse-toi, et ne te laisse pas intimider par les vétérans aux gros sabots B)

Je n’ai pas le choix non plus pour le tout pointeur sur les structures B)
Notre prof nous a dit qu’il ne veut plus voir de “.”… alors comme c’est lui qui note il vaut mieux pas le contrarier. Pour l’instant ça me va je m’en sort bien avec le tout pointeurs.

[quote=“bluelambda, post:17, topic: 31032”]Je n’ai pas le choix non plus pour le tout pointeur sur les structures B)
Notre prof nous a dit qu’il ne veut plus voir de “.”… alors comme c’est lui qui note il vaut mieux pas le contrarier. Pour l’instant ça me va je m’en sort bien avec le tout pointeurs.[/quote]
J’ose espérer que le prof vous a bien précisé qu’il voulait ça dans le cadre précis d’un exercice sur les pointeurs, et qu’il ne recommande pas ça de façon générale. Sinon c’est un dangereux malade, et il faut le buter. B)

il a quand meme l’air un peu c^w^w bizarre votre prof …

Il nous a dit ça en cours.
Enfin il a l’air simpa et il a l’air de savoir de quoi il parle. Bref on verra bien ce que ça donne tout ça.