Voici une petite question de noob motivé.
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui
contient les données, et des fonctions qui s'appliquent à ce struct.
Par exemple, dans le header, j'ai ceci :
/* ---------- HEADER ---------- */
typedef struct
(int data1
,int data2
) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct"
pourraient être, par inadvertance (ou plutôt feignantise ;-) ),
directement modifiées sans passer par les fonctions.
Est-il possible de pouvoir déclarer les données "data1" et "data2" dans
l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de
MonStruct ne puisse se faire qu'en passant par les fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
-TSalm
Voici une petite question de noob motivé. Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
/* -------------------------------- */ -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}.
TSalm <tsalm@free.fr> writes:
Bonjour,
Voici une petite question de noob motivé.
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct
qui contient les données, et des fonctions qui s'appliquent à ce
struct.
Par exemple, dans le header, j'ai ceci :
/* ---------- HEADER ---------- */
typedef struct
(int data1
,int data2
) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct"
pourraient être, par inadvertance (ou plutôt feignantise ;-) ),
directement modifiées sans passer par les fonctions.
Est-il possible de pouvoir déclarer les données "data1" et "data2"
dans l'implémentation (le fichier ".c"), de façon à ce que
l'utilisation de MonStruct ne puisse se faire qu'en passant par les
fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
Voici une petite question de noob motivé. Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
/* -------------------------------- */ -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}.
Pascal J. Bourguignon
TSalm writes:
Merci pour cette réponse tout à fait intéressante. Par contre, ça oblige à faire un cast au début de chaques fonctions. Est-ce que ça ne risque pas de ralentir l'exécution de cette fonction ?
Non.
Autre question, pourquoi utiliser "extern" pour les prototypes de fonctions ? Est-ce une recommandation pour garder une compatibilité avec certains compilateurs ?
Je ne suis pas au courrant des derniers standard. Je ne vois pas pourquoi ils renonceraient à la déclaration extern.
Merci pour cette réponse tout à fait intéressante.
Par contre, ça oblige à faire un cast au début de chaques
fonctions. Est-ce que ça ne risque pas de ralentir l'exécution de
cette fonction ?
Non.
Autre question, pourquoi utiliser "extern" pour les prototypes de
fonctions ? Est-ce une recommandation pour garder une compatibilité
avec certains compilateurs ?
Je ne suis pas au courrant des derniers standard. Je ne vois pas
pourquoi ils renonceraient à la déclaration extern.
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Merci pour cette réponse tout à fait intéressante. Par contre, ça oblige à faire un cast au début de chaques fonctions. Est-ce que ça ne risque pas de ralentir l'exécution de cette fonction ?
Non.
Autre question, pourquoi utiliser "extern" pour les prototypes de fonctions ? Est-ce une recommandation pour garder une compatibilité avec certains compilateurs ?
Je ne suis pas au courrant des derniers standard. Je ne vois pas pourquoi ils renonceraient à la déclaration extern.
Voici une petite question de noob motivé. Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
Merci pour cette réponse tout à fait intéressante. Par contre, ça oblige à faire un cast au début de chaques fonctions. Est-ce que ça ne risque pas de ralentir l'exécution de cette fonction ? Autre question, pourquoi utiliser "extern" pour les prototypes de fonctions ? Est-ce une recommandation pour garder une compatibilité avec certains compilateurs ? ps: Je viens de voir que je m'étais planté dans la déclaration de mon struct, dsl.
Voici une petite question de noob motivé.
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct
qui contient les données, et des fonctions qui s'appliquent à ce
struct.
Par exemple, dans le header, j'ai ceci :
/* ---------- HEADER ---------- */
typedef struct
(int data1
,int data2
) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct"
pourraient être, par inadvertance (ou plutôt feignantise ;-) ),
directement modifiées sans passer par les fonctions.
Est-il possible de pouvoir déclarer les données "data1" et "data2"
dans l'implémentation (le fichier ".c"), de façon à ce que
l'utilisation de MonStruct ne puisse se faire qu'en passant par les
fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
Merci pour cette réponse tout à fait intéressante.
Par contre, ça oblige à faire un cast au début de chaques fonctions.
Est-ce que ça ne risque pas de ralentir l'exécution de cette fonction ?
Autre question, pourquoi utiliser "extern" pour les prototypes de
fonctions ? Est-ce une recommandation pour garder une compatibilité avec
certains compilateurs ?
ps: Je viens de voir que je m'étais planté dans la déclaration de mon
struct, dsl.
Voici une petite question de noob motivé. Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
D'avance merci pour vos avis ou éventuelles remarques.
Merci pour cette réponse tout à fait intéressante. Par contre, ça oblige à faire un cast au début de chaques fonctions. Est-ce que ça ne risque pas de ralentir l'exécution de cette fonction ? Autre question, pourquoi utiliser "extern" pour les prototypes de fonctions ? Est-ce une recommandation pour garder une compatibilité avec certains compilateurs ? ps: Je viens de voir que je m'étais planté dans la déclaration de mon struct, dsl.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Y a-t-il une raison particulière de passer par un void*? On peut tout à
fait déclarer une struct sans la définir sur place, et ça n'empêche pas
d'utiliser des pointeurs vers elle.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Samuel DEVULDER
Le 28/01/2012 17:39, TSalm a écrit :
Bonjour,
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
Tu peux te débrouiller en rendant opaque le contenu de MonStruct pour l'utilisateur en utilisant la compilation conditionnelle. Je te propose de faire ainsi (en gros)
void code(Monstruct *p) { p->opaque = ???? // en fait on ne sait rien de ce // qu'il y a dans "opaque" Il faut // passer par les fonctions Monstruct_*() MonStruct_fait_quelquechose(p, 42); } ----8<-----------------------------------------8<---------------------
Bon c'est l'idée. Tu peux varier à l'infini ou presque.
sam.
Le 28/01/2012 17:39, TSalm a écrit :
Bonjour,
Mon problème est que les données("data1" et "data2") de "MonStruct"
pourraient être, par inadvertance (ou plutôt feignantise ;-) ),
directement modifiées sans passer par les fonctions.
Est-il possible de pouvoir déclarer les données "data1" et "data2" dans
l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de
MonStruct ne puisse se faire qu'en passant par les fonctions ?
Tu peux te débrouiller en rendant opaque le contenu de MonStruct pour
l'utilisateur en utilisant la compilation conditionnelle. Je te propose
de faire ainsi (en gros)
void code(Monstruct *p) {
p->opaque = ???? // en fait on ne sait rien de ce
// qu'il y a dans "opaque" Il faut
// passer par les fonctions Monstruct_*()
MonStruct_fait_quelquechose(p, 42);
}
----8<-----------------------------------------8<---------------------
Bon c'est l'idée. Tu peux varier à l'infini ou presque.
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
Tu peux te débrouiller en rendant opaque le contenu de MonStruct pour l'utilisateur en utilisant la compilation conditionnelle. Je te propose de faire ainsi (en gros)
void code(Monstruct *p) { p->opaque = ???? // en fait on ne sait rien de ce // qu'il y a dans "opaque" Il faut // passer par les fonctions Monstruct_*() MonStruct_fait_quelquechose(p, 42); } ----8<-----------------------------------------8<---------------------
Bon c'est l'idée. Tu peux varier à l'infini ou presque.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est ce que l'on veut éviter.
Y a-t-il une raison particulière de passer par un void*? On peut tout à
fait déclarer une struct sans la définir sur place, et ça n'empêche pas
d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est
ce que l'on veut éviter.
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est ce que l'on veut éviter.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est ce que l'on veut éviter.
On la définit dans le fichier .c, qui n'est pas visible par l'utilisateur.
Enfin en tout cas j'ai l'impression que "pimpl" est la réponse à la question d'origine.
Y a-t-il une raison particulière de passer par un void*? On peut tout à
fait déclarer une struct sans la définir sur place, et ça n'empêche pas
d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est
ce que l'on veut éviter.
On la définit dans le fichier .c, qui n'est pas visible par l'utilisateur.
Enfin en tout cas j'ai l'impression que "pimpl" est la réponse à la
question d'origine.
Y a-t-il une raison particulière de passer par un void*? On peut tout à fait déclarer une struct sans la définir sur place, et ça n'empêche pas d'utiliser des pointeurs vers elle.
Pour ce que j'en sais, il faut finir par définir ces structures. C'est ce que l'on veut éviter.
On la définit dans le fichier .c, qui n'est pas visible par l'utilisateur.
Enfin en tout cas j'ai l'impression que "pimpl" est la réponse à la question d'origine.
Samuel DEVULDER
Une typo s'est glissée... un détail mineur qui n'entache pas le principe.
L'idée est que si MONSTRUCT_INTERNAL est défini ou pas on a pas la même définiton de MonStruct.
- pour l'utilisateur: typedef struct {const char opaque[la taille de la struct];} MonStruct;
- pour le developpeur: typedef struct MonStruct_internal MonStruct;
sam.
Manuel Pégourié-Gonnard
Bonjour,
TSalm scripsit :
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
Oui, il n'y a que peu de choses à changer à ton code.
/* ----- implémentation ----- */ struct MonStruct { int data1; int data2; };
/* définitions de fonctions inchangées */ /* -------------------------- */
C'est ce qu'on appelle une structure opaque il me semble. J'imagine que c'est pour permettre ce genre de choses que le standard spécifie que « All pointers to structure types shall have the same representation and alignment requirements as each other. »
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui
contient les données, et des fonctions qui s'appliquent à ce struct.
Par exemple, dans le header, j'ai ceci :
/* ---------- HEADER ---------- */
typedef struct
(int data1
,int data2
) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct"
pourraient être, par inadvertance (ou plutôt feignantise ;-) ),
directement modifiées sans passer par les fonctions.
Est-il possible de pouvoir déclarer les données "data1" et "data2" dans
l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de
MonStruct ne puisse se faire qu'en passant par les fonctions ?
Oui, il n'y a que peu de choses à changer à ton code.
/* ----- implémentation ----- */
struct MonStruct {
int data1;
int data2;
};
/* définitions de fonctions inchangées */
/* -------------------------- */
C'est ce qu'on appelle une structure opaque il me semble. J'imagine que
c'est pour permettre ce genre de choses que le standard spécifie que
« All pointers to structure types shall have the same representation and
alignment requirements as each other. »
--
Manuel Pégourié-Gonnard - http://people.math.jussieu.fr/~mpg/
Venant du monde de la POO, j'ai démarrer un pgm en C avec un struct qui contient les données, et des fonctions qui s'appliquent à ce struct. Par exemple, dans le header, j'ai ceci : /* ---------- HEADER ---------- */ typedef struct (int data1 ,int data2 ) MonStruct;
Mon problème est que les données("data1" et "data2") de "MonStruct" pourraient être, par inadvertance (ou plutôt feignantise ;-) ), directement modifiées sans passer par les fonctions. Est-il possible de pouvoir déclarer les données "data1" et "data2" dans l'implémentation (le fichier ".c"), de façon à ce que l'utilisation de MonStruct ne puisse se faire qu'en passant par les fonctions ?
Oui, il n'y a que peu de choses à changer à ton code.
/* ----- implémentation ----- */ struct MonStruct { int data1; int data2; };
/* définitions de fonctions inchangées */ /* -------------------------- */
C'est ce qu'on appelle une structure opaque il me semble. J'imagine que c'est pour permettre ce genre de choses que le standard spécifie que « All pointers to structure types shall have the same representation and alignment requirements as each other. »