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

const et argument de fonction

9 réponses
Avatar
Lucas Levrel
Bonjour,

Dans la Math Kernel Library d'Intel, les fonctions BLAS sont déclarées
comme ceci (exemple) :
float cblas_sasum(const int N, const float *X, const int incX);

Quel est l'intérêt de déclarer constants N et incX, étant donné le passage
par valeur du C ? Au retour de la fonction, la variable passée en argument
ne peut pas avoir été modifiée.

Est-ce que ça aide le compilateur à optimiser quelque chose ?

--
LL

9 réponses

Avatar
Wykaaa
Lucas Levrel a écrit :
Bonjour,

Dans la Math Kernel Library d'Intel, les fonctions BLAS sont déclarées
comme ceci (exemple) :
float cblas_sasum(const int N, const float *X, const int incX);

Quel est l'intérêt de déclarer constants N et incX, étant donné le
passage par valeur du C ? Au retour de la fonction, la variable passée
en argument ne peut pas avoir été modifiée.

Est-ce que ça aide le compilateur à optimiser quelque chose ?



Cela interdit d'affecter le paramètre dans la fonction alors que sinon,
ok, c'est le temporaire qui est affecté mais le compilateur ne dit rien.
Cela renforce donc la sécurité du code.
Avatar
Marc Boyer
Le 20-02-2012, Lucas Levrel a écrit :
Bonjour,

Dans la Math Kernel Library d'Intel, les fonctions BLAS sont déclarées
comme ceci (exemple) :
float cblas_sasum(const int N, const float *X, const int incX);

Quel est l'intérêt de déclarer constants N et incX, étant donné le passage
par valeur du C ?



Je rate peut-être quelque chose aussi, mais ça n'a aucune incidence
sur le code qui appelle la fonction.

Après, ça change des choses dans le code de la fonction elle même.
Ca peut aider le compilateur à voir que dans le code de la fonction,
ces 'variables' ne seront pas modifiées.
On peut aussi se dire que ça renforce la qualité du code,
dans une vision où les paramètres n'ont pas à être modifiés.
Mais ne pas être const permet aussi d'utiliser moins de variables
int fact(int n){
assert( n >= 0 );
int res= 1;
while (n>1){
res*= n;
n--;
}
}

De toute façon, ça me semble une faiblesse du C: ça met dans
l'interface un choix d'implantation (ne pas modifier les paramètres).

Marc Boyer
--
À mesure que les inégalités regressent, les attentes se renforcent.
François Dubet
Avatar
Antoine Leca
Lucas Levrel écrivit :
float cblas_sasum(const int N, const float *X, const int incX);

Quel est l'intérêt de déclarer constants N et incX, étant donné le
passage par valeur du C ?



Les objets sont invariants dans toute la portée.


Est-ce que ça aide le compilateur à optimiser quelque chose ?



Cela dépend sûrement des compilateurs et de la manière dont chacun
d'entre eux est conçu, mais de manière globale oui : il s'agit d'une
information supplémentaire donnée dès le départ de l'analyse ; le
compilateur peux donc considérer cet acquis pour faire ses choix. Et le
temps qui est gagné en choisissant d'entrée le bon choix peut être
utilement consacré à d'autre tâches, dont cela améliore l'efficacité
globale du compilateur.

Maintenant il est clair que du fait d'une part de l'état du C au moment
où les compilateurs ont été développés, et de l'habitude d'autre part
des programmeurs qui comme toi ne considèrent pas utile de fournir cette
information "const", les compilateurs actuels réalisent systématiquement
une analyse globale de la fonction pour déterminer si une variable est
modifiée ou pas, avant de procéder à la moindre simplification ou
attribution d'espace (algorithmes de coloration).


Autre intérêt de déclarer "const int N" : si ces objets sont passés par
référence à un sous-programme, ils devront être déclarés (const int *)
dans ce sous-programme pour que le programme soit compilable ; en
contre-partie, le compilateur pourra réutiliser une valeur en registre
sans relire l'objet en mémoire, même en présence de code « compliqué »:
for( ; test_externe(&N) ; )
utilise_registre(N); // grâce à const, N invariant


Antoine
Avatar
Pierre Maurette
Lucas Levrel :
Bonjour,

Dans la Math Kernel Library d'Intel, les fonctions BLAS sont déclarées comme
ceci (exemple) :
float cblas_sasum(const int N, const float *X, const int incX);

Quel est l'intérêt de déclarer constants N et incX, étant donné le passage
par valeur du C ? Au retour de la fonction, la variable passée en argument ne
peut pas avoir été modifiée.

Est-ce que ça aide le compilateur à optimiser quelque chose ?



Peut-être ? ;-)

Je surveille également le fil car une réponse m'intéresse. J'avais un
peu utilisé C-BLAS et LAPACK mais iumpossible de retrouver une bonne
raison précise à ce qualifieur.
Ce dont je me souviens c'est que cblas_sasum() emballe une fonction
écrite en Fortran qui attend des adresses pour N et incX, peut-être y
a-t-il là une possibilité d'optimisation ? Peut-être également des
versions spécifiques sont-elles liées si N et incX sont des valeurs
/fréquentes/ et connues à la compilation ?

--
Pierre Maurette
Avatar
Lucas Levrel
Merci pour les réponses, très instructives.


Le 21 février 2012, Antoine Leca a écrit :
des programmeurs qui comme toi ne considèrent pas utile de fournir cette
information "const",



C'est pas très gentil. Je n'ai pas dit ça. Je n'ai même pas demandé
« Est-ce que ça a un intérêt », j'ai demandé « Quel est l'intérêt ».

--
LL
Avatar
espie
In article <jhvq79$fo4$,
Antoine Leca wrote:

Autre intérêt de déclarer "const int N" : si ces objets sont passés par
référence à un sous-programme, ils devront être déclarés (const int *)
dans ce sous-programme pour que le programme soit compilable ; en
contre-partie, le compilateur pourra réutiliser une valeur en registre
sans relire l'objet en mémoire, même en présence de code « compliqué »:
for( ; test_externe(&N) ; )
utilise_registre(N); // grâce à const, N invariant



Tu t'es fait pieger par ton choix de vocabulaire, il n'y a pas de references
en C...

Le const du C est un transfuge mal adapte depuis le C++... il y a deux ou
trois gags de semantiques qui montrent que les gens qui ont fait la norme
du C n'ont pas tout compris... et puis de toutes facons, en l'absence de
surcharge, c'est tout pourri (par exemple, il est impossible d'ecrire
strchr() sans un cast).

(et maintenant que C++ a les move, l'importance des const ref est grandement
diminuee. il y avait meme des exemples anti-intuitifs dans les presentations
de going native ou passer des parametres par valeur au lieu de const reference
*amelioraient* les performances en fournissant des opportunites supplementaires
d'optimisation a la bibliotheque/compilateur).


Vu le systeme de types du C, de toutes les manieres, le compilo sera oblige
de tout verifier de toutes facons. Les const y sont, dans le meilleur des
cas, un commentaire raisonnablement verifie par le compilateur. C'est pas
totalement inutile, mais c'est loin d'etre la panacee !
Avatar
Wykaaa
Marc Espie a écrit :
In article <jhvq79$fo4$,
Antoine Leca wrote:
Autre intérêt de déclarer "const int N" : si ces objets sont passés par
référence à un sous-programme, ils devront être déclarés (const int *)
dans ce sous-programme pour que le programme soit compilable ; en
contre-partie, le compilateur pourra réutiliser une valeur en registre
sans relire l'objet en mémoire, même en présence de code « compliqué »:
for( ; test_externe(&N) ; )
utilise_registre(N); // grâce à const, N invariant



Tu t'es fait pieger par ton choix de vocabulaire, il n'y a pas de references
en C...

Le const du C est un transfuge mal adapte depuis le C++... il y a deux ou
trois gags de semantiques qui montrent que les gens qui ont fait la norme
du C n'ont pas tout compris... et puis de toutes facons, en l'absence de
surcharge, c'est tout pourri (par exemple, il est impossible d'ecrire
strchr() sans un cast).

(et maintenant que C++ a les move, l'importance des const ref est grandement
diminuee. il y avait meme des exemples anti-intuitifs dans les presentations
de going native ou passer des parametres par valeur au lieu de const reference
*amelioraient* les performances en fournissant des opportunites supplementaires
d'optimisation a la bibliotheque/compilateur).


Vu le systeme de types du C, de toutes les manieres, le compilo sera oblige
de tout verifier de toutes facons. Les const y sont, dans le meilleur des
cas, un commentaire raisonnablement verifie par le compilateur. C'est pas
totalement inutile, mais c'est loin d'etre la panacee !




Je suis d'accord avec toi mais c'est tout de même plus propre de
signaler dans le code le fait que la valeur passée ne doit pas changer
dans l'appelé.
Avatar
espie
In article <4f462adb$0$12518$,
Wykaaa wrote:

Je suis d'accord avec toi mais c'est tout de même plus propre de
signaler dans le code le fait que la valeur passée ne doit pas changer
dans l'appelé.



Ah oui, ca c'est sur. J'ai pris des habitudes de const correctness depuis...
1990 ou 1991, de memoire ? et encore plus affirmees depuis que je fais aussi
du C++. Mais il faut etre honnete, c'est plus de la documentation qu'autre
chose cote C !
Avatar
Antoine Leca
Marc Espie a écrit :
In article <jhvq79$fo4$,
Antoine Leca wrote:

Autre intérêt de déclarer "const int N" : si ces objets sont passés par
référence à un sous-programme, [...]



Tu t'es fait pieger par ton choix de vocabulaire, il n'y a pas de references
en C...



:-)
Justement, il n'y a de ce fait pas de barbarisme... à moins bien sûr de
considérer que « passage par référence » implique obligatoirement un
opérateur syntaxique effectuant cette opération sémantique !


Le const du C est un transfuge mal adapte depuis le C++...



Oui

il y a deux ou trois gags de semantiques qui montrent que les gens
qui ont fait la norme du C n'ont pas tout compris...



Mmmm, pas sûr qu'ils n'aient pas compris ; des objections, certaines
véhémentes et certaines venant de gens très bien considérés, celles de
DMR étant probablement la plus connue, ont été fournies en temps et
heure ; le résultat est effectivement un compromis, et en tant que tel
n'est pas parfait.

et puis de toutes facons, en l'absence de surcharge, c'est tout pourri
(par exemple, il est impossible d'ecrire strchr() sans un cast).



L'exemple de strchr(), ou mieux de strstr(), sous-tend que l'écriture de
la bibliothèque standard devrait représenter la quintessence de la
programmation en C.
Je pense au contraire qu'une des raisons d'être de la bibliothèque
standard est de fournir les briques à rajouter au langage pour obtenir
un ensemble cohérent.

Par exemple, à mon avis Ada83 est passablement lourd au niveau des
entrées-sorties du fait de l'obligation d'utiliser un appel de
sous-programme pour chaque élément ; a contrario les fonctions
variadiques du C permettent d'avoir printf qui permet d'écrire plus
facilement des programmes.


Par ailleurs, le transtypage en C est un problème en soi du fait de ses
aspects « peut tout faire ». C++98 avait rajouté les syntaxes
compliquées genre reinterpret_cast pour tenter de freiner leur usage,
mais ce n'est pas « l'esprit du C » (en tous cas celui du XXe siècle.)


[...] mais c'est loin d'etre la panacee !



Tout-à-fait d'accord


Antoine