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

5 6 7 8 9
Avatar
Marwan Burelle
On Tue, 27 Apr 2004 18:55:37 +0200
Cyril Guibourg wrote:

C permet de faire aussi du crade sans avoir mal à la tête. Reste que
si on "sait" comment tourne une machine, ont code en C autrement que
celui qui n'a jamais vu autre chose que du SQL*Net.


Ce n'est pas simplement le fait de savoir comment fonctionne la machine
que de comprendre "en gros" comment le code sera traduit par le
compilateur.

Pour prendre un exemple simpliste, si on reprend le bon vieux bof avec
strcopy (genre le code exemple de "Smashing the stack for fun and
profit"), on peut évneutellement comprendre que copier une string dans
un buffer trop petit peut poser des problèmes, par contre, comprendre
que derrière cela permet de modifier le comportement du programme de
manière dangereuse, cela nécessite de savoir comment l'envirronnement
d'une fonction est représenté sur la pile (on peut même imaginer qu'un
compilateur décide de faire les choses pas comme tout le monde, et par
exemple de ne pas mettre les variables locales sur la pile ... )

En fait toute cette problèmatique vient du fort lien qu'il y a entre la
sémantique du C et sa traduction en code machine.

Si on prend SQL, par contre, on est dans le cas d'un langage déclaratif
avec la très forte volonté de dissocier le code est son interprétation
(le but ici est de faire des optimisations "on the fly" dépend de la
représentation de la base, de son contenu et de ses indexes ... )

C'est pour ça, que j'aurais tendance à dire qu'écrire en C sans un
minimum de background sur la compilation est "risqué" ...

--
Burelle Marwan,
Equipe Bases de Donnees - LRI
http://www.cduce.org
( | )

Avatar
Marwan Burelle
On Tue, 27 Apr 2004 18:38:57 +0200
mips wrote:

On Tue, 27 Apr 2004 15:29:49 +0200
Marwan Burelle wrote:

Mais j'ai bien compris ... mais ce que l'on te dis, c'est que
justement, la sémantique des opérateurs feignants est clair. Il faut
juste la lire de la bonne façon.


Oui et dans certains il faut aussi prendre la precaution de la relire
au cas ou ...


Oui, toujours, mais bon, si tu lis bien linéairement, c'est relativement
clair ....


Enfin, pour moi, ce n'est pas franchement un exemple particulier de
code illisible.


La encore j'ai un doute sur la comprehension de ce que j'appelle
"illisible".



Quelque chose dont le sens ne parraît pas immédiat en première lecture ?

On ne parle pas de lire des centaines de lignes en une seule passe.
Par contre, une trentaine ... mais bien sûr, si tous les cas où l'on


Quand je fais de la maintenance de code, c'est rare que je n'ai que 30
lignes de code a consulter. Et quand je dit rare je suis genereux.



Hé, mipsounet, quand je parle de 30 lignes, je parle de bloc de 30
lignes. Je doute que tu sois capable de te taper en une seule passe des
fichier C de plusieures centaines de lignes (sinon, je veux bien
t'embaucher pour corriger les projets de mes étudiants, ah merde c'est
pas en C ;)

n'est pas forcément plus lisible (en plus dans le cas du double if,
on se retrouve avec une hierarchie de "if" suffisament ambigue, pour
justement rendre les choses moins lisible.)


La par contre je te suis plus.


Ben, je suis désolé, mais un :

if (truc1)
if (truc2)
.... ;

Je trouve ça moins lisible que :

if (truc1 && truc2)
.... ;

Surtout s'il traine d'autre if imbriqués dans le coin ...

Le truc, c'est que dans les constructions if, la fin du if n'est pas
toujours clair, imagine quelque chose du genre :

if (truc)
if (truc1)
if (truc2)
e1 ;
else e2 ;

Il n'est pas toujours facile de voir à quoi se rapporte le "else", même
avec la bonne indentation (d'ailleur, le "if ..."/"if ... else ..." est
le cas classsique de shift/reduce conflict en yacc ... )

(classiquement, ce code est mal indendté, volontairement, pour montrer
comment des if imbriqués peuvent être trompeur, pour faire ce que
l'indentation "sous-entend", il faudrait rajouter quelques accolades ...
)


Maintenant, comme je l'ai dit, ça dépend de ce que tu utilises.
Typiquement, le while (--i) pour savoir ce qui se passe ... en une
seule passe ...


Pourtant ca saute aux yeux !!! ;)


i = 0 ;
...
while (--i) { ... }

En fonction de ce que tu as dans les premiers "...", ça peut devenir
conton de se demander pourquoi se code boucle à l'infini ... surtout que
l'on a pas forcément "i = 0" explicitement ... alors que

i = 0 ;
...
while (i--) { ... }

par contre, s'arrète ...

La différence ne se voit pas forcément au premier coup d'oeil ...

Bref tu l'auras ecrit comme ca :
if (!page_dir[j] && !malloc_make_chunks(j)) return 0;

Une chose est sure on est pas du tout d'accord :)))


C'est intéressant de ne pas être d'accord ... si la discussion est
constructive ;)

Maintenant, comme je l'ai déjà dis, le && ou || me gène moins que les if
imbriqués ... et puis, forcément, ça dépend du contexte ! ;)

--
Burelle Marwan,
Equipe Bases de Donnees - LRI
http://www.cduce.org
( | )


Avatar
Thierry Thomas
Mercredi 28 avril 2004 à 07:53 GMT, Marwan Burelle a écrit :
On Tue, 27 Apr 2004 18:55:37 +0200
Cyril Guibourg wrote:

C permet de faire aussi du crade sans avoir mal à la tête. Reste que
si on "sait" comment tourne une machine, ont code en C autrement que
celui qui n'a jamais vu autre chose que du SQL*Net.



8< 8< 8<

Si on prend SQL, par contre, on est dans le cas d'un langage déclaratif


Juste pour dire que SQL*Net, c'était le protocole utilisé par Oracle
entre deux bases ou un client / un serveur, et que ça devait bien être
écrit en C ;-)
--
Th. Thomas.


Avatar
Thierry Thomas
Mercredi 28 avril 2004 à 20:09 GMT, Cyril Guibourg a écrit :

As-tu déjà vu un programme écrit par un dba pour faire du SQL*Net via ProC ?


Euh, non, mais j'en ai écrit moi-même...

Moi, j'ai même eu droit au "plaisir" d'en débugger certains qui se terminaient
via SIGSEV quand ils n'oubliaient pas de tomber en marche.


Le ProC, c'est toujours un peu fumeux... Je suis en train de migrer des
progs qui tournent en exploitation depuis une dizaine d'années sur AIX
4.x / Oracle 7.x vers AIX 5.2 / Oracle 8, et cette migration m'a révélé
des erreurs de syntaxe, et pourtant les programmes tournaient, on se
demande comment, et on passait bien aux endroits fautifs...
--
Th. Thomas.

Avatar
pornin
According to Cyril Guibourg :
C'est ce que je voulais dire par le <<on "sait" comment tourne une
machine>>, j'aurais du écrire <<avoir fait de l'assembleur>>. Ce n'est
pas un pré-requis mais cela aide énormément.


C'est ce que je raconte habituellement : pour vraiment bien programmer,
il faut connaître ce qui se passe en-dessous, idéalement jusqu'au niveau
du transistor (voire plus bas !). Donc avoir fait de l'assembleur (pour
plusieurs architectures distinctes !), éventuellement avoir fait joujou
avec un FPGA ou quelque chose du genre.

En bref, on maîtrise bien un langage comme le C quand on devient capable
d'écrire un compilateur pour ce langage. À ce moment-là, il n'y a plus
de magie, juste de la technique, et on peut faire des choses lisibles,
robustes et optimisées.


Évidemment, ceci ne correspond pas à une réalité industrielle, et dans
la pratique, il faut bien faire avec des programmeurs qui ne connaissent
le langage que par une collection d'astuces apprises sur le tas et par
coeur.


--Thomas Pornin

Avatar
pornin
According to Cyril Guibourg :
Diantre ! J'admets que celui qui connait parfaitement ce qu'il se passe
grâce aux dopants, les sorties tri-state, etc dispose d'une vision encore
plus fine mais comment cela peut-il être un avantage pour écrire du C ?


C'est indirect :

Pour bien écrire du C il faut connaître l'assembleur sous-jacent, les
performances des opérations et optimisations possibles.

Pour bien connaître l'assembleur avec les performances et optimisations
possibles, ça aide beaucoup de savoir comment ça marche au niveau
en-dessous. On peut avoir une connaissance empirique (de type "par
coeur") de ces données, mais c'est mieux de comprendre ce qui se passe.
Par exemple, on peut apprendre par coeur qu'une division entière prend
beaucoup plus de temps sur un processeur moderne qu'une multiplication
entière avec des opérandes de même taille -- mais c'est mieux de savoir
pourquoi.


--Thomas Pornin

Avatar
Miod Vallat
Oui d'abord, remetons les choses en place. Un troll ca sent pas, ca
pue.


Tu es prié de cesser tes attaques diffammatoires et injustifiées contre
la profession.

Avatar
Miod Vallat
Et quoi que tu dises, sur ce point, le langage C ne se classe pas la
catégorie des langages fournis avec planche savonnée au savon noir.


Sauf les opérateurs binaires (&,|, ^) de priorité supérieure aux
opérateurs de test...


J'ai bien dit plus haut que connaître les priorités des opérateurs
faisait partie des connaissances de base à acquérir sur le langage...

Ça c'est une vraie planche savonnée. Heureusement beaucoup de
compilateurs mettent un warning quand l'expression n'est pas
parenthésée, mais ils ne sont pas obligés.


Je ne suis pas de cet avis, personnellement...


Avatar
talon
Thomas Pornin wrote:
According to Cyril Guibourg :
Diantre ! J'admets que celui qui connait parfaitement ce qu'il se passe
grâce aux dopants, les sorties tri-state, etc dispose d'une vision encore
plus fine mais comment cela peut-il être un avantage pour écrire du C ?


C'est indirect :

Pour bien écrire du C il faut connaître l'assembleur sous-jacent, les
performances des opérations et optimisations possibles.

Pour bien connaître l'assembleur avec les performances et optimisations
possibles, ça aide beaucoup de savoir comment ça marche au niveau
en-dessous. On peut avoir une connaissance empirique (de type "par
coeur") de ces données, mais c'est mieux de comprendre ce qui se passe.
Par exemple, on peut apprendre par coeur qu'une division entière prend
beaucoup plus de temps sur un processeur moderne qu'une multiplication
entière avec des opérandes de même taille -- mais c'est mieux de savoir
pourquoi.

Si je peux me permette d'intervenir sur un sujet aussi "high brain", tu

as un point de vue de mathématicien: tu veux comprendre pourquoi la
division est plus lente que la multiplication. Le point de vue du
physicien, c'est qu'il se fout royalement de ce pourquoi, il mesure
combien de temps prend la multiplication, combien la division, et ils
est trés content de ce résultat.


--Thomas Pornin


--

Michel TALON


Avatar
espie
In article <c6qilk$1nt0$,
Michel Talon wrote:
Thomas Pornin wrote:
According to Cyril Guibourg :
Diantre ! J'admets que celui qui connait parfaitement ce qu'il se passe
grâce aux dopants, les sorties tri-state, etc dispose d'une vision encore
plus fine mais comment cela peut-il être un avantage pour écrire du C ?


C'est indirect :

Pour bien écrire du C il faut connaître l'assembleur sous-jacent, les
performances des opérations et optimisations possibles.

Pour bien connaître l'assembleur avec les performances et optimisations
possibles, ça aide beaucoup de savoir comment ça marche au niveau
en-dessous. On peut avoir une connaissance empirique (de type "par
coeur") de ces données, mais c'est mieux de comprendre ce qui se passe.
Par exemple, on peut apprendre par coeur qu'une division entière prend
beaucoup plus de temps sur un processeur moderne qu'une multiplication
entière avec des opérandes de même taille -- mais c'est mieux de savoir
pourquoi.

Si je peux me permette d'intervenir sur un sujet aussi "high brain", tu

as un point de vue de mathématicien: tu veux comprendre pourquoi la
division est plus lente que la multiplication. Le point de vue du
physicien, c'est qu'il se fout royalement de ce pourquoi, il mesure
combien de temps prend la multiplication, combien la division, et ils
est trés content de ce résultat.


Ah ? c'est plus lent ?
Moi qui croyais que les deux algo pouvaient avoir les memes performances.
Ma memoire me jouerait des tours ?



5 6 7 8 9