Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pointeur vers une fonction de classe static

32 réponses
Avatar
candide
Bonjour,

Avez-vous déjà rencontré du code qui appelle depuis un fichier a.c une
fonction g qui prend en argument l'adresse d'une fonction f définie
static dans un autre fichier b.c ?

En plus je vois pas comment c'est possible à moins d'utiliser une
variable globale.

Je pose la question car K.N. King évoque cette possibilité dans son
manuel de C et je voudrais savoir si ça a un quelconque intérêt et si ça
correspond à une pratique réelle.

[Je ne vois pas trop l'intérêt puisque si on définit une fonction en
classe statique c'est pour limiter son accès depuis un fichier externe à
sa définition et donc c'est circonvenir cette limitation d'accès que
d'utiliser un pointeur vers cette fonction.]


Si ma question n'est pas claire, je placerai ici l'extrait du livre de King.


Merci

10 réponses

1 2 3 4
Avatar
Antoine Leca
En news:488f4a6e$0$7251$, candide va escriure:
Avez-vous déjà rencontré du code qui appelle depuis un fichier a.c une
fonction g qui prend en argument l'adresse d'une fonction f définie
static dans un autre fichier b.c ?

[Je ne vois pas trop l'intérêt puisque si on définit une fonction en
classe statique c'est pour limiter son accès depuis un fichier
externe à sa définition



Non.
La classe statique sert à limiter l'accès au NOM de la fonction (ou de
l'objet). Cela n'a pas d'influence directe sur l'accès au CONTENU (la
fonction ou l'objet en lui-même).


Antoine
Avatar
candide
Jean-Marc Desperrier a écrit :

Pour un exemple industriel, c'est le modèle qu'utilise l'interface
PKCS#11 v2 :
http://www.rsa.com/rsalabs/node.asp?id!33




In code we trust !! Pour être plus précis, quels fichiers (.c et .h),
quelles fonctions static, quelles structures à initialiser ?
Tu veux dire que par exemple les pointeurs sur fonctions qui sont dans
struct CK_FUNCTION_LIST (fichier pkcs11.h) vont être initialisés vers
des fonctions static ? Mais comment peut-on le savoir sans disposer des
fichiers d'implémentation ?

Désolé je suis un peu péquenot du C ;)
Avatar
candide
FrihD a écrit :

L'intérêt c'est le même que pour une fonction static "non appellée par
pointeur" : moins de symboles, moins de risques de conflits de noms,
code plus simple à appréhender.



Juste ça ?


Par exemple, tu peux faire:
typedef int (*fonction_de_comparaison)(void*,void*);
et ta tri_par_bulle prendra alors une liste d'élèments et la
fonction_de_comparaison.



Mais quel intérêt de rendre la fonction de comparaison static ?


L'avantage: ça permet de s'abstraire de beaucoup de choses et de faire
du code très modulaire.




A vrai dire, j'ai pas vraiment compris en quoi.
Avatar
espie
In article <48932f74$0$14747$,
candide wrote:

A vrai dire, j'ai pas vraiment compris en quoi.




Tu nous la fait boulet, aujourd'hui ? ;-)

Imagine un vrai projet. Assemble a partir de 15 bibliotheques.

Avec 35000 lignes de code dans ces bibliotheques... plus 15000 lignes
de projet independant.

Ca te fait quelques milliers de symboles a gerer. Tu t'imagines quoi ?
que tout le monde s'est concerte pour que tous les noms de symboles
soient uniques ? En pratique, non. Il faut des conventions de nommage.
Et si tu as des fonctions qui ne servent a rien en dehors d'une bibliotheque,
c'est une bonne idee de les rendre privees, ce qui se fait a coup de static.
(en laissant de cote tous mecanismes non standards supplementaires, hein,
on parle de C classique ici).

Transpose ca sur un gros projet, en multipliant par 10 ou 100 les chiffres
donnes ci-dessus. Tout ce qui va pouvoir t'aider pour organiser le bordel
ambiant va etre utile.


... et en vrai, si les gens ne pensent pas un minimum aux risques de
collision, tu vas tomber tres, tres vite sur des collisions entre noms
de fonctions, parce que l'espace des noms de fonctions courants est
tout petit, et que les gens pensent toujours aux memes noms en premier.
Avatar
candide
Antoine Leca a écrit :

Non.
La classe statique sert à limiter l'accès au NOM de la fonction (ou de
l'objet). Cela n'a pas d'influence directe sur l'accès au CONTENU (la
fonction ou l'objet en lui-même).



Donc l'avantage c'est juste pour limiter la pollution de l'espace de
noms ou c'est un truc plus futé que ça ?

L'utilisation de static c'est quand même une affaire de conception
logicielle et c'est censé mieux organiser le code, non ? Ça veut dire
que la fonction est locale à un fichier et donc qu'_en principe_, elle
ne sert que dans le fichier où elle est définie. Donc qu'on veuille
malgré tout utiliser une telle fonction ailleurs heurte un peu mon bon
sens paysan et je me dis qu'il doit y a voir une subtile astuce que
j'aimerais comprendre.
Avatar
FrihD
Salut
L'utilisation de static c'est quand même une affaire de conception
logicielle et c'est censé mieux organiser le code, non ? Ça veut dire
que la fonction est locale à un fichier et donc qu'_en principe_, elle
ne sert que dans le fichier où elle est définie. Donc qu'on veuille
malgré tout utiliser une telle fonction ailleurs heurte un peu mon bon
sens paysan et je me dis qu'il doit y a voir une subtile astuce que
j'aimerais comprendre.


L'intérêt zéroième, c'est l'espace de nom, ce qui va avec l'organisation
du code. Par exemple tu fais une librairie HTTP. Si tu utilises un timer
POSIX, tu auras besoin d'une fonction "timeout" pour anuller une
requête. L'utilisateur de ta librairie HTTP, aura comme interface
"annulle_req", mais il n'aura pas à appeler "timeout" lui même. Autant
ne pas lui offrir un symbole permettant de le faire. Pourtant, la
"librairie signals" aura besoin de la fonction.

L'intérêt premier c'est que le compilateur peut facilement trouver une
optimisation "genre inline" s'il remarque qu'on n'utilise jamais son
"pointeur". Mais gdb dans ces cas là est un peu paumé parfois.

--Lucas
Avatar
Alexandre BACQUART
candide wrote:
Antoine Leca a écrit :

Non.
La classe statique sert à limiter l'accès au NOM de la fonction (ou de
l'objet). Cela n'a pas d'influence directe sur l'accès au CONTENU (la
fonction ou l'objet en lui-même).



Donc l'avantage c'est juste pour limiter la pollution de l'espace de
noms ou c'est un truc plus futé que ça ?



L'avantage, c'est d'abord d'empêcher les autres modules d'accéder à la
fonction/variable *à travers son nom*. Limiter la pollution de l'espace
global n'est en fait qu'un effet de bord bienvenu puisque le nom n'est
simplement pas exporté pour satisfaire l'objectif principal.

L'utilisation de static c'est quand même une affaire de conception
logicielle et c'est censé mieux organiser le code, non ? Ça veut dire
que la fonction est locale à un fichier et donc qu'_en principe_, elle
ne sert que dans le fichier où elle est définie.



C'est souvent le cas, mais static n'a d'influence que sur la portée ("du
nom") de la fonction/variable.

Cela suffit, puisqu'alors la seule manière possible d'accéder à l'objet,
c'est de manière indirecte à travers un pointeur éventuel qui ne peut
être défini que dans le même module de l'objet (il n'y a donc aucun viol
de la volonté de l'implémentation à cacher le nom).

Donc qu'on veuille
malgré tout utiliser une telle fonction ailleurs heurte un peu mon bon
sens paysan et je me dis qu'il doit y a voir une subtile astuce que
j'aimerais comprendre.



C'est tout à ton honneur, mais la vérité est qu'il n'y a pas d'astuce.
La question est de savoir comment tu veux qu'un objet puisse être
utilisé dans un module externe :

- directement avec son nom (pas static)
- indirectement avec un pointeur (static + pointeur pas static)
- pas du tout (static)


--
Alex
Avatar
candide
Alexandre BACQUART a écrit :

L'avantage, c'est d'abord d'empêcher les autres modules d'accéder à la
fonction/variable *à travers son nom*. Limiter la pollution de l'espace
global n'est en fait qu'un effet de bord bienvenu puisque le nom n'est
simplement pas exporté pour satisfaire l'objectif principal.



OK.


C'est souvent le cas, mais static n'a d'influence que sur la portée ("du
nom") de la fonction/variable.



Si je peux me permettre, il me semble que le terme approprié n'est pas
"portée" ( ie "scope") mais plutôt "liaison" (ie "linkage").


Cela suffit, puisqu'alors la seule manière possible d'accéder à l'objet,
c'est de manière indirecte à travers un pointeur éventuel qui ne peut
être défini que dans le même module de l'objet (il n'y a donc aucun viol
de la volonté de l'implémentation à cacher le nom).



OK.


La question est de savoir comment tu veux qu'un objet puisse être
utilisé dans un module externe :

- directement avec son nom (pas static)
- indirectement avec un pointeur (static + pointeur pas static)
- pas du tout (static)





OK. Merci de ces explications fort claires.
Avatar
candide
Merci de ta réponse.


FrihD a écrit :

L'intérêt zéroième, c'est l'espace de nom,



OK, je n'avais pas réalisé l'importance de ce point.

L'intérêt premier c'est que le compilateur peut facilement trouver une
optimisation "genre inline"



Je n'avais jamais entendu parler de cet argument d'optimisation (mais ma
culture en programmation est assez réduite).
Avatar
candide
Marc Espie a écrit :

A vrai dire, j'ai pas vraiment compris en quoi.




Tu nous la fait boulet, aujourd'hui ? ;-)



Aujourd'hui, hier et demain !! N'est pas boulet qui veut, il y en a qui
se concentreraient très fort et qui ne pourraient devenir aussi boulet
que moi. Donc en fait je vois cela comme un compliment ;)

Il y a aussi que j'ai tendance à considérer que les choses seraient plus
compliquées que souvent elles ne le sont.

J'ai bien lu et compris les explications que tu donnes concernant la
collision des noms. Comme j'ai assez peu d'expérience en programmation
et en particulier une expérience nulle en matière de gros projet,
j'avais du mal à concevoir l'importance de ce problème.

Ce que je regrette c'est que les ouvrages sur le C mettent si peu
l'accent sur ces problèmes. Même des ouvrages avancés (comme par exemple
le gros pavé de Blaess sur la programmation en C sous Linux) ne
systématisent pas ce problème de l'espace de nom et ne donnent pas
l'astuce des pointeurs vers des fonctions statiques. Je viens de passer
K&R au peigne fin, il ne disent quasiment RIEN des fonctions static.
Si vous avez des références qui traitent de ces questions, ça m'intéresse.

Je me permets de rappeler que mon intérêt pour le C standard est guidé
essentiellement par le besoin de comprendre comment on peut créer une
documentation innovante du langage C, à la fois d'apprentissage et de
référence et qui soit exhaustive, intelligible, facile à lire, concise
et tournée vers l'utilisateur, oui, rien que ça ! (en particulier le
traitement ne doit pas être purement scolaire ou intellectuel comme
c'est trop souvent le cas).
1 2 3 4