OVH Cloud OVH Cloud

Passage de structure en paramètre d'une fonction

55 réponses
Avatar
Rémi BERTHOLET
Bonjour,

J'ai un code qui ressemble =E0 cela :

struct MaStructure
{
int x;
int y;
};


void MaFonction(struct MaStructure)
{
...
}


Je peux appeler ma fonction en faisant :
struct MaStructure data =3D {0,0};
MaFonction(data);

Mais je voudrais faire quelque chose comme cela :
MaFonction({0,0});

Existe t'il une syntaxe en C pour le faire ?

Merci

5 réponses

2 3 4 5 6
Avatar
espie
In article <i2uakj$hdk$,
Antoine Leca wrote:
Non, suite entre autres à une intervention de DMR, il n'y avait que
const et volatile dans la norme C89
Pas le truc le plus propre de C89, d'ailleurs.
En fait, c'est tout le concept (C89) de /qualificateur/ qui fait
problème, cela n'a pas toujours le niveau de précision suffisant car il
s'agit souvent d'ajouter des informations complémentaires sur le type,
donc plus ou moins de gris, mais pas de discriminer (blanc ou noir)
entre par exemple entiers ou flottants, ou entre différents espaces
mémoire. Et bien sûr, quand on veut définir une couleur, on a des
appréciations différentes suivant les points de vue...




Oui, de toutes facons, const en C89 est au final une connerie. Vouloir
faire comme C++, et insister qu'on a bien tout compris en inventant une
semantique fausse parce que sinon, il faudrait tout revoir le langage,
c'etait oblige que ca merdoie... const ne peut pas "fonctionner" sans
surcharge de toutes facons (si const marchait, il n'y aurait pas besoin de
cast dans l'implementation de strstr...).
Avatar
Gabriel Dos Reis
Antoine Leca writes:

[...]

Quant au reste, c'est un peu connerie sur connerie. Je me souviens bien si
restrict etait present dans C89 ou pas...





| Non, suite entre autres à une intervention de DMR, il n'y avait que
| const et volatile dans la norme C89
| Pas le truc le plus propre de C89, d'ailleurs.

Pour const, non. En 2007, à la réunion d'Hawaï, j'ai demand é à BEH
comment se fait-il qu'une variable de type entier declaré 'const', et
initialisée avec une expression constante ne peut pas être utilis ée
comme une expression constante.

'volatile', non merci.

| En fait, c'est tout le concept (C89) de /qualificateur/ qui fait
| problème, cela n'a pas toujours le niveau de précision suffisan t car il
| s'agit souvent d'ajouter des informations complémentaires sur le typ e,
| donc plus ou moins de gris, mais pas de discriminer (blanc ou noir)
| entre par exemple entiers ou flottants, ou entre différents espaces
| mémoire. Et bien sûr, quand on veut définir une couleur, o n a des
| appréciations différentes suivant les points de vue...

oui, et le comité C99 a cru bon devoir ajouter cette horreur de
« restrict. »
(Tu n'es pas obligé de les défendre, mais si tu étais dans l a salle.)

« extern inline » ? Une plaisanterie grotesque.

« compound literal » ? une farce.

-- Gaby
Avatar
espie
In article <i2um24$dd9$,
Antoine Leca wrote:
Ce qui était évident à l'époque, c'est qu'il était facile de tromper (le
compilateur ou soi-même) en abusant restrict à mauvais escient et en
passant des pointeurs vers des objets se recouvrant plus ou moins : le
comportement est bien sûr indéfini, mais cette fois c'est plus grave que
d'habitude, car il y a de bonnes chances que le programme devienne faux
lorsque l'optimisation va « en s'améliorant »...
D'un autre côté, sur les possibles non-respects de restrict dans un
code, l'espoir était que l'analyse du compilateur le détectât et le
signalât (notez l'utilisation du subjonctif) : je ne sais pas ce qu'il
en est advenu dans la réalité.



ca a pris quelques annees avant que gcc commence a detecter des undefined
behavior sur i++ et sur des problemes d'aliasing. Meme maintenant, c'est
relativement incomplet...
Avatar
Yves Lambert
On Mon, 26 Jul 2010 12:16:54 +0000 (UTC)
(Marc Espie) wrote:

Mais il n'y a pas consensus dans
la communaute des Unix, en grande partie a cause d'Ulrich Drepper, qui
pense que les fonctions avec de taille de buffer sont inutiles au vrai
programmeur...



Tu fais référence à ce message, je présume ?

http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html
Il me semble que le ton est quelque peu sarcastique...

Pour prévenir les problèmes soulevés par Drepper dans ce thread (voir
ses autres messages), un bon usage de ces fonctions serait un truc dans
le style (ne me baffez pas si je me goure):

char * source;
char * dest;
size_t taille_buffer=VALEUR;
char *dest=malloc(taille_buffer);
size_t taille_chaine;
// [...]
taille_chaine=strlcpy(dest,source,taille_buffer)
if (taille_chaine < taille_buffer-1) // tout va bien
{ // [...]
}
else // il faut peut-être envisager de réallouer de la mémoire pour dest
{// ou lever un drapeau pour signaler que dest est tronquée ; le cas où
// strlen(source) == taille_chaine -1 est à traiter aussi
}

Ce qui peut être fait en amont en comparant strlen(source) et
taille-buffer-1 (aucun problème s'il y a égalité) et alors qu'est-ce
qui empêche d'utiliser strcpy() ou strncpy() ?

--
Il est souvent trop tôt pour savoir s'il n'est pas trop tard.
-+- Pierre Dac -+-
Avatar
espie
In article ,
Yves Lambert wrote:
On Mon, 26 Jul 2010 12:16:54 +0000 (UTC)
(Marc Espie) wrote:

Mais il n'y a pas consensus dans
la communaute des Unix, en grande partie a cause d'Ulrich Drepper, qui
pense que les fonctions avec de taille de buffer sont inutiles au vrai
programmeur...



Tu fais référence à ce message, je présume ?

http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html
Il me semble que le ton est quelque peu sarcastique...

Pour prévenir les problèmes soulevés par Drepper dans ce thread (voir
ses autres messages), un bon usage de ces fonctions serait un truc dans
le style (ne me baffez pas si je me goure):

char * source;
char * dest;
size_t taille_buffer=VALEUR;
char *dest=malloc(taille_buffer);
size_t taille_chaine;
// [...]
taille_chaine=strlcpy(dest,source,taille_buffer)
if (taille_chaine < taille_buffer-1) // tout va bien
{ // [...]
}
else // il faut peut-être envisager de réallouer de la mémoire pour dest
{// ou lever un drapeau pour signaler que dest est tronquée ; le cas où
// strlen(source) == taille_chaine -1 est à traiter aussi
}



C'est faux. Il n'y a pas de cas particulier pour
strlen(source) == taille_chaine-1

le test de probleme s'ecrit sous la forme:
if (taille_chaine >= taille_buffer)

Je ne sais pas d'ou tu as sorti ta doc pour strlcpy. Moi j'ai des exemples
corrects dans la mienne.

Ce qui peut être fait en amont en comparant strlen(source) et
taille-buffer-1 (aucun problème s'il y a égalité) et alors qu'est-ce
qui empêche d'utiliser strcpy() ou strncpy() ?



Je vais me repeter, mais il n'y a toujours pas de bonne raison d'utiliser
strncpy, qui va remplir TOUT le buffer de toutes facons.

Apres, les consequences d'une erreur de logique sur strlcpy, c'est une chaine
tronquee. Sur strcpy, c'est un buffer overflow...

L'erreur de raisonnement que tu fais est la meme que Drepper: elle suppose
que le programmeur est infaillible, et qu'on fait tous suffisamment
attention. Si tu lis son argumentation en detail, il considere que quelqu'un
qui a besoin de strlcpy est indigne d'etre programmeur.

C'est faux. On fait tous des erreurs, personne n'est infaillible. Et il
suffit d'un instant d'inattention pour faire une erreur critique dans 4000
lignes de code.

Les choses ne sont pas en "noir et blanc". strlcpy offre:
- une meilleure resistance aux pannes;
- est plus simple a utiliser correctement (surtout avec son comparse strlcat),
ce qui libere de precieux neurones pour corriger d'autres bugs;
- permet d'ecrire du code uniforme qui sera relativement plus simple a
auditer. C'est beaucoup plus simple de se convaincre de l'absence de buffer
overflows dans du code base sur strlcpy/strlcat que sur strcpy/strcat. Les
idiomes "similaires" bases sur strncpy/strncat (?) sont plus complexes (en
particulier, il faut mettre le 0 final dans strncpy si on veut etre sur
de l'avoir, strlcpy n'a pas ce probleme). La-aussi, ca permet au relecteur
de degager de precieux neurones pour voir d'autres problemes.

Une autre facon de voir les choses, c'est de dire que strcpy/strcat sont
des fonctions "simples" d'un autre temps, a l'epoque ou personne ne se
preoccupait trop de problemes de securite.

strlcpy/strlcat sont une tentative pour permettre de les remplacer de la
facon la plus simple et la plus debile possible. En particulier, ces
fonctions demandent d'ajouter le minimum vital par rapport a strcpy/strcat
si on veut verifier l'absence d'overflow (typiquement, juste un parametre
en plus, et un resultat qui se teste simplement).

99% du code qu'on ecrit est completement cretin et pedestre. strlcpy
permet de garder ce code cretin et pedestre, et donc de se consacrer
aux bouts qui en valent la peinee.

Et il y a des tonnes de programmeurs dans le monde qui peuvent beneficier
de strlcpy. La premiere etape, c'est sans doute un peu d'humilite. A savoir
bien se rendre compte qu'on VA faire des erreurs et qu'on VA avoir des bugs
dans son code (et meme s'il y a vraiment des programmeurs infaillibles,
ils vont travailler avec d'autres personnes, qui vont certainement introduire
des problemes en modifiant leur code).
2 3 4 5 6