OVH Cloud OVH Cloud

Beuuurk !

87 réponses
Avatar
Cyrille Szymanski
En me balladant tranquillement dans les sources de la libc de
FreeBSD, j'ai rencontré un petit bout de code effrayant au
détour de malloc.c :

/* If it's empty, make a page more of that size chunks */
if (!page_dir[j] && !malloc_make_chunks(j))
return 0;

C'est pas très beau ça quand même, mais on dirait que ça
fonctionne... pour combien de temps ?

--
cns

10 réponses

1 2 3 4 5
Avatar
manu
mips wrote:

/* look for a page */
if (page_dir[j] == NULL) {
/* It's empty, try to make a page */
if (malloc_free_chunks(j) == NULL)
return(NULL); /* failed page alloc */
}


Seulement si tu alligne 10 conditions comme ca, le code devient
illisible.

J'aurai tendence à ecrire ca comme ca:

/*
* look for a page,
* if it's empty, try to make a page
*/
if ((page_dir[j] == NULL) ||
(malloc_free_chunks(j) == NULL)) {
return(NULL); /* failed page alloc */
}

--
Emmanuel Dreyfus
Un bouquin en français sur BSD:
http://www.eyrolles.com/php.informatique/Ouvrages/9782212112443.php3


Avatar
talon
Emmanuel Dreyfus wrote:
mips wrote:

/* look for a page */
if (page_dir[j] == NULL) {
/* It's empty, try to make a page */
if (malloc_free_chunks(j) == NULL)
return(NULL); /* failed page alloc */
}


Seulement si tu alligne 10 conditions comme ca, le code devient
illisible.

J'aurai tendence à ecrire ca comme ca:

/*
* look for a page,
* if it's empty, try to make a page
*/
if ((page_dir[j] == NULL) ||
(malloc_free_chunks(j) == NULL)) {
return(NULL); /* failed page alloc */
}



Ca ne fait pas exactement la même chose que le machin initial.
Le machin initial avait un &&, avec l'évaluation paresseuse le
premier échec suffisait. Le tien a un || ce qui nécessite dans tous les
cas les deux évaluations. Non pas que ça fasse une différence dans le
cas d'espèce mais ça en ferait une si l'un des deux tests avait des
effets de bord.


--

Michel TALON


Avatar
talon
Michel Talon wrote:
Ca ne fait pas exactement la même chose que le machin initial.
Le machin initial avait un &&, avec l'évaluation paresseuse le
premier échec suffisait. Le tien a un || ce qui nécessite dans tous les
cas les deux évaluations.


Non, je ferais mieux de ne pas poster le matin!
!A && !B est vrai dés que A==NULL, sinon il faut évaluer B et c'est vrai
si B==NULL

(A==NULL)||(B==NULL) est vrai dans les mêmes conditions. Donc les deux
formes sont bien équivalentes sous l'évaluation paresseuse.


--

Michel TALON

Avatar
Cyrille Szymanski
On 2004-04-24, Michel Talon wrote:
Michel Talon wrote:
Ca ne fait pas exactement la même chose que le machin initial.
Le machin initial avait un &&, avec l'évaluation paresseuse le
premier échec suffisait. Le tien a un || ce qui nécessite dans tous les
cas les deux évaluations.


Non, je ferais mieux de ne pas poster le matin!
!A && !B est vrai dés que A==NULL, sinon il faut évaluer B et c'est vrai
si B==NULL

(A==NULL)||(B==NULL) est vrai dans les mêmes conditions. Donc les deux
formes sont bien équivalentes sous l'évaluation paresseuse.


Oui c'est la loi de de Morgan :
!(a&&b) == (!a)||(!b)
!(a||b) == (!a)&&(!b)

Comme quoi manipuler ce genre d'expression en faisant attention aux
effets de bord est loin d'être trivial.

--
cns


Avatar
Erwan David
Cyrille Szymanski écrivait :

Oui c'est la loi de de Morgan :
!(a&&b) == (!a)||(!b)
!(a||b) == (!a)&&(!b)


Ça c'est en logique, ça ne tient pas compte des évaluations
paresseusses...


--
Real programs don't eat cache

Avatar
talon
Cyrille Szymanski wrote:
On 2004-04-24, Michel Talon wrote:
Michel Talon wrote:
Ca ne fait pas exactement la même chose que le machin initial.
Le machin initial avait un &&, avec l'évaluation paresseuse le
premier échec suffisait. Le tien a un || ce qui nécessite dans tous les
cas les deux évaluations.


Non, je ferais mieux de ne pas poster le matin!
!A && !B est vrai dés que A==NULL, sinon il faut évaluer B et c'est vrai
si B==NULL

(A==NULL)||(B==NULL) est vrai dans les mêmes conditions. Donc les deux
formes sont bien équivalentes sous l'évaluation paresseuse.


Oui c'est la loi de de Morgan :
!(a&&b) == (!a)||(!b)
!(a||b) == (!a)&&(!b)

Comme quoi manipuler ce genre d'expression en faisant attention aux
effets de bord est loin d'être trivial.



Non, justement c'est pas la loi de Morgan, c'est ce qui m'avait induit à
mon post faux. S'il n'y avait pas d'évaluation paraisseuse ce serait
purement et simplement la loi de Morgan en effet. En tenant compte de
l'évaluation paraisseuse il y a tout intérêt à refaire le raisonnement
soigneusement, et pas de tête en vitesse comme j'avais fait.


--

Michel TALON



Avatar
talon
Cyrille Szymanski wrote:
On 2004-04-24, Michel Talon wrote:
Michel Talon wrote:
Ca ne fait pas exactement la même chose que le machin initial.
Le machin initial avait un &&, avec l'évaluation paresseuse le
premier échec suffisait. Le tien a un || ce qui nécessite dans tous les
cas les deux évaluations.


Non, je ferais mieux de ne pas poster le matin!
!A && !B est vrai dés que A==NULL, sinon il faut évaluer B et c'est vrai
si B==NULL

(A==NULL)||(B==NULL) est vrai dans les mêmes conditions. Donc les deux
formes sont bien équivalentes sous l'évaluation paresseuse.


Oui c'est la loi de de Morgan :
!(a&&b) == (!a)||(!b)
!(a||b) == (!a)&&(!b)

Comme quoi manipuler ce genre d'expression en faisant attention aux
effets de bord est loin d'être trivial.



Non, justement c'est pas la loi de Morgan, c'est ce qui m'avait induit à
mon post faux. S'il n'y avait pas d'évaluation paresseuse ce serait
purement et simplement la loi de Morgan en effet. En tenant compte de
l'évaluation paresseuse il y a tout intérêt à refaire le raisonnement
soigneusement, et pas de tête en vitesse comme j'avais fait.


--

Michel TALON



Avatar
Cyrille Szymanski
On 2004-04-24, Erwan David wrote:
Oui c'est la loi de de Morgan :
!(a&&b) == (!a)||(!b)
!(a||b) == (!a)&&(!b)


Ça c'est en logique, ça ne tient pas compte des évaluations
paresseusses...


M'est avis que le paradigme des évaluations paresseuses se transpose
à de Morgan.

a&&b => pour a faux on n'évalue pas b
(!a)||(!b) => pour a faux (le 1er terme est vrai) on n'évalue pas b
=> pour a vrai les deux sont évalués

a||b => pour a vrai ou n'évalue pas b
(!a)&&(!b) => pour a vrai (le premier terme est faux) on n'évalue pas b
=> pour a faux les deux sont évalués

--
cns


Avatar
Cyrille Szymanski
On 2004-04-24, Emmanuel Dreyfus wrote:
J'aurai tendence à ecrire ca comme ca:

/*
* look for a page,
* if it's empty, try to make a page
*/
if ((page_dir[j] == NULL) ||
(malloc_free_chunks(j) == NULL)) {
return(NULL); /* failed page alloc */
}


Il me semble que vous avez écrit "if the page doesn't exist or
could not be created" alors qu'avec un && ça donne "if the page
doesn't exist and could not be created".

Si vous voulez à tout prix utiliser un || :

if( (page_dir[j] != NULL) ||
(malloc_free_chunks(j) != NULL) ) {
/*
* the j_th page exists, or was successfully created
*/
} else {
/*
* the j_th page didn't exist and could not be created
*/
return NULL;
}

On retrouve de Morgan entre les deux phrases, a||b==!(!a&&!b).

--
cns

Avatar
DINH Viêt Hoà

Mais ça ne simplifie pas le code, puisqu'il devient plus gros,
verticalement...


Pas sur ...


C'est pourtant chose manifeste : la réécriture en deux tests occupe au
moins une ligne de plus, sauf à l'écrire dans un style trop dense pour
être honnête.


c'est sûr que sur un terminal vt100, ça prend du coup plus de 10% de
l'espace d'affichage vertical T.T

--
DINH V. Hoa,

"La connerie c'est génétique" -- sunZ



1 2 3 4 5