Bonjour,
J'ai un problème avec les structs implantées par valeurs mais stockées par référence. Voilà ce que je veux dire:
Imaginons une struct S qui fait disons qq mots de taille. Par nature, pour ainsi dire, elle peut être une pure donnée, autrement dit avoir une sémantique dite de valeur. Son implantation en fait donc un type de struct tout simple; les quelques routines spécifiques à ce type peuvent recevoir la struct (et non un pointeur). (En particulier, si elle est conceptuellement non mutable.) Le point clé est que la création d'une S est directe et que donc le code client reçoit bien une S et non pas une référence, un pointeur, et le manipule ainsi.
Mais que se passe-t-il si cette struct est intégrée dans d'autres types de données, à un niveau supérieur? Dans ce cas, pour diverses raisons (poids d'un S en lui-même, uniformité de taille dans une union, ...) il peut être souhaitable de stocker une référence et non plus la struct elle-même.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 S s = s_make (...) ; // manier s tel que // et non pas S * s = s_new (...) ;
Alors c'est là que je suis un peu perdu, j'arrive pas à penser le problème. Le danger là est bien que s est une donnée locale et donc un pointeur sur elle cesse d'être valide dès qu'on sort du bloc. On devrait allouer s sur le tas. Correct?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 S s = s_make (...) ; x.s = & s_data ;
Mais quand est-ce que le code ci-dessus cesse d'être sûr, en fait? Normalement le problème avec un pointeur sur une donéée locale se pose lorsque ce pointeur est retourné par la fonction. Ici, il n'y a rien de tel: il est placé dans une structure. Alors, qu'est-ce qui se passe? [1]
Et plus généralement, quand est-ce que je peux ou pas stocker par référence une structure non allouée sur le tas?
Mon problème exact est celui-ci: j'ai un type Texte (dont j'ai parlé sur ce forum) qui est assez léger (2 mots) et immuable. Donc, tout l'implantation est par valeur, il n'y a pas une réf dans toute le module. Un avantage est que les structs elles-mêmes ne sont pas allouées (seul leur contenu l'est) et donc aussi n'ont pas à âtre libérées. Mais à un plus haut niveau le type Text fait partie d'une union dont tous les autres memebreas ont la taille d'un mot
* soit parce que la donnée fait cette taille au maximum,
* soit parce qu'elle sont des données complexes mais naturellement maniées par référence (entre autres parce qu'elle sont mutables, elles).
Mon problème est que je voudrais stocker des textes là par référence pour ne pas doubler la taille de l'union, mais aussi éviter d'allouer les struct Text sur le tas.
c'est possible?
Merci,
denis
[1] PS: J'ai l'impression suivante (qui peut être fausse). Si la structure de donnée 'x' dans laquelle la réf à 's' est placée est elle-même locale, ne sort pas de la fonction directement ou indirectement, alors ça roule. Sinon, on devrait avoir un problème.
Mais ça ne fait que déplacer le problème que j'arrive pas à penser. En fait, le coeur de mon interrogation semble être: dans quelles situations de programmation est-ce qu'on peut faire ça ou pas ? dans quelles situations est-ce qu'on doit allouer une struct-donnée sur le tas qui n'a pas besoin de l'etre à la base pour des raisons sémantiques ? Et surtout, à quoi correspondent conceptuellement les situations ou une struct-donnée peut ou non rester non allouée ? que signifient de telles situations et donc comment les reconnaître par le sens qu'elles ont ?
Partager