[gull] Php/MsSQL obsoletes?

Leopoldo Ghielmetti Leopoldo.Ghielmetti at a3.epfl.ch
Wed Sep 28 15:54:48 CEST 2005


On Wed, 2005-09-28 at 15:18, Daniel Cordey wrote:
> On Wednesday 28 September 2005 14:47, Leopoldo Ghielmetti wrote:
> 
> > Mais tu peut très bien écrire une chose comme celle la (en ANSI C):
> >
> > module.c:
> > void fonction(int a)
> > {
> >   printf("%d\n", a);
> > }
> >
> > module.h:
> > void fonction();
> >
> > main.c:
> > include "module.h"
> >
> > int main()
> > {
> >   float b = 1.0;
> >   fonction(b);
> >   return 0;
> > }
> 
> Exact, c'est la raison pour laquelle j'ai toujours milite pour que la partie 
> de definition de la signature de la fonction soit UNIQUE et partagee entre la 
> definition dans la fonction et la declaration en externe. ceci est facile a 
> realiser avec des #ifdef.
> 
> Exemple de ce genre de fichier qui est genere par un GUI :
> 
> ...
> 
> /* Function name        */
> /* Is it the main program or the function's code ? */
> #if     defined(_MAIN_SOURCE) && defined(_NPCaseConfirm_SOURCE)
> #    define     NAME_SOURCE     main
> #else
> #    define     NAME_SOURCE     NPCaseConfirm
> #endif  /* _MAIN_SOURCE && _NPCaseConfirm_SOURCE        */
> /* Function type        */
> #define TYPE_SOURCE     void
> 
> /* Toggle Extern-declaration/definition */
> /* is it a declaration of a definition ? */
> #ifdef  _NPCaseConfirm_SOURCE
> #  define       EXTERN_SOURCE
> #  define       DECLARATION
> #else   /* _NPCaseConfirm_SOURCE        */
> #  define       EXTERN_SOURCE   extern
> #  define       DECLARATION     ;
> #endif  /* _NPCaseConfirm_SOURCE        */
> 
> #if defined(__STDC__) || defined(__cplusplus)
> #  define       ARG_LIST_SOURCE (API *Api, CaseData *casedata)
> #else   /* __STDC__ || __cplusplus      */
> #  ifdef        _NPCaseConfirm_SOURCE
> #    define     ARG_LIST_SOURCE ()
> #  else /* _NPCaseConfirm_SOURCE        */
> #    define     ARG_LIST_SOURCE ()
> #  endif        /* _NPCaseConfirm_SOURCE        */
> #endif  /* __STDC__ || __cplusplus      */
> 
> /* The real function declaration        */
> EXTERN_SOURCE TYPE_SOURCE       NAME_SOURCE ARG_LIST_SOURCE DECLARATION
> 
> /* Undefine all names used      */
> #  undef        EXTERN_SOURCE
> #  undef        TYPE_SOURCE
> #  undef        NAME_SOURCE
> #  undef        ARG_LIST_SOURCE
> #  undef        DECLARATION
> 
> Le fichier du code de la focntion a :
> 
> #define _NPCaseConfirm_SOURCE
> 
> Ainsi, seul le fichier de source "recoit" la definition alors que tout autre 
> appel "recoit" une declaration lors de l'include de ce fichier. 
> 
> C'est simple et ca permet d'eviter le probleme mentionne. C'est beton et le 
> compilateur m'a correctement signale les erreurs dans mon code a chaque fois. 
> C'est le genre de choses qui vous sauve la vie et vous permet de vous passer 
> des debuggeurs symboliques.

C'est élégant, mais je préfère limiter l'utilisation des ifdef, par
contre je ne lésine pas sur l'utilisation des define. :-)

Le problème c'est qu'a chaque fois que j'utilise des ifdef/define mon
chef me dit que le code est illisible, qu'il doit pouvoir être lu par M.
Tout le Monde et que ça deviant peu maintenable, ...

Donc pour finir je me réduit a des simples choses comme:
module.h:
#if !defined( __MODULE_H__ )
#  define __MODULE_H__ 

typedef struct mon_type_cache mon_type_cache;

extern int va_variable;

int fonction1(int a);

int fonction2(mon_type_cache* a);

#endif

module.c:
#include "module.h"

struct mon_type_cache
{
  ...
};

int fonction1(int a)
{
  ...
}

int fonction2(mon_type_cache* a)
{
  ...
}

Faire bien attention à l'include dans le .c, si on oublie ça c'est
fichu, et dès qu'il y a une incohérence le compilateur la trouve
immédiatement, ceci sans utiliser des ifdef, donc ça ne nuit pas à la
lisibilité.

Par contre j'ai trouvé des modifications faites a mon code par d'autre
gents du style:
module.h:

#if !defined( __MODULE_H__ )
#  define __MODULE_H__ 

typedef struct mon_type_cache mon_type_cache;

extern int va_variable;

int fonction1(int a);

int fonction2(mon_type_cache* a);

void * fonction3();

#endif

int autre_variable = 5;

module.c:
...

évidemment voir des choses comme ça, ça fait mal, mais comme tu disait,
on ne peut pas empêcher à un programmeur de mal programmer.

> > Et ça passe très bien. Et la plus part des programmes sont encore écrits
> > comme ça car c'était une syntaxe courante dans les années 80 et encore
> > beaucoup de programmeurs ont ce réflexe.
> 
> Je sais... c'est de l'amateurisme !
> 
> > Ceci est possible car dans C la vérification des types n'est pas
> > obligatoire et on peut s'en passer. Donc on risque d'avoir des problèmes
> > de typage.
> 
> Oui, mais comme dans tout langage, le profesionnel adopte des disciplines. ca 
> me parait indispensable, meme si ce n'est pas obligatoire.
> 
> 
> > Le fait que je sais qu'on ne perd pas en précision ne m'aide pas
> > forcement, il faut toujours avoir bien à l'esprit le type de chaque
> > variable pour être sûr de ne pas changer le type sans s'en rendre compte
> > (chose qui est bien plus facile de ce qu'on pourrait croire, surtout si
> > on utilise des anciennes librairies). Et ceci peut causer pas mal de
> > problèmes si on accède au matériel ou si on travaille au niveau du bit.
> 
> Oui, le danger reside surtout dans les "masquages" de probleme. Dans le cas 
> de :
> 
> int i;
> short x;
> int j;
> 
> i = 2;
> ...
> x = i;
> ...
> j = x;
> 
> Le danger viend du fait que l'on est persuade de manipuler un int avec j, 
> alors que cette valeurs a ete tronquee plus tout en passant par x = i. On 
> peut chercher parfois longtemps ce genre de probleme.
> 
> > Mais il s'agit quand même d'une conversion qui n'a pas été explicitée
> > par le programmeur.
> 
> Oui, mais autorissee car sans danger. 
> >
> > > > c = a <--- Erreur, int <> float
> > >
> > > Non plus... Dans le cas inverse, ca devrait etre flaguer car un float
> > > (32 bits IEEE) donne 6.7 chiffres significatifs, alors que int nous
> > > donne un peu plus de 9 chiffres significatifs...
> > >
> > > > Tandis que C laisse passer et considère ça comme:
> > > >
> > > > b = (long)a
> > > >
> > > > c = (float)a
> > >
> > > C'est exactement l'operation qui est effectuee. Et cela ne pose aucun
> > > probleme du tout. Par contre, C permet d'ecrire ceci :
> >
> > Bien sûr qui peut poser des problèmes car la variable à changé de nature
> > et le programmeur n'en sait rien.
> 
> Non, pas a proprement parle. b est toujours un long, contenant une valeur 
> long, et c un float contenant un float. Le contenu de a n'a pas change non 
> plus. Le probleme est beaucoup plus subtile quand on manipule des valeurs 
> 'unsigned'... ca, c'est mesquin :-)

:-)

> > Pas totalement vrai, p.e. le compilateur cc de Sun c'est une vraie merde
> > de ce côté.
> 
> Naturellement, tu mentionnes le pire... SUN a toujours privilegie la 
> performance et leur compilateur est deliberement 'loose' concernant des 
> points essentiels. Cela a induit de mauvaises pratiques (et comprehension du 
> langage C) chez de tres nombreux programmeurs :-(

Oui, mais tout le monde à travaillé tôt ou tard sur un Sun, je l'ai fait
aussi, et au début je croyais qu'il était très bien (évidemment je ne
connaissais pas les autres). Après quand j'ai découvert les Alpha je me
suis dit que c'était très bien, et effectivement à l'époque c'était
certainement vrai.

Beaucoup de gents sont encore convaincus aujourd'hui que Sun c'est "the
Best" et continuent impunément à faire des conversions long <-> int <->
long sans se soucier des éventuels problèmes de portabilité (et de
maintenabilité).

> > J'ai vu du code qui donne 1000 Warning sur le gcc et sur le 
> > cc Alpha de Digital et seulement 100 sur le compilateur cc de Sun. Et
> > parfois c'était des vraies merdes. 
> 
> parfois seulement ?
> 
> > S'ils ont utilisé un compilateur 
> > comme celui la, qui même avec toutes les options de compilation ne donne
> > rien, il est normal qu'ils n'ont pas vu certaines fautes. Il est vrai
> > qu'ils auraient pu utiliser lint ou tout autre programme similaire. Mais
> > je ne dirais pas qu'il s'agit d'une négligence commise sciemment, juste
> > d'une négligence qui peur aussi être due simplement à l'ignorance.
> 
> Et l'igonrance est coupable quand on choisi de rester ignorant. Le standard 
> ANSI existe depuis trop longtemps pour qu'on puisse pretendre a l'ignorance. 
> La lecture du standard eclaire justement un certain nombre de points 
> dangereux dont tout programmeur C devrait etre averti.

Mais encore il faut que le programmeurs sachent qu'il y a des choses qui
pourraient les intéresser dans leur travail.
Ok, la ou peut discuter longuement. De toute façon je suis aussi de
l'avis qu'il faut essayer de toujours bien se documenter. Moi j'ai
appris en utilisant beaucoup de langages (y compris l'assembleur) et
donc en ayant vu les côtés positifs et négatifs de chacun. Aujourd'hui
j'ai une certaine façon de programmer qui est assez propre bien que loin
d'être parfaite, mais comme chaque méthode elle est bien à moi, chose
qui fait que mes codes sont très propres et marchent généralement bien
mais qu'en même temps fait que quelqu'un qui n'a pas la même vision que
moi trouve difficile à comprendre. P.e. dans le petit bout de code,
mon_type_cache faut obligatoirement le manipuler via des pointeurs, donc
tous ceux qui ne maîtrisent pas les pointeurs ou ils en ont carrément
peur verront mon code comme totalement incompréhensible (c'est
généralement la remarque de mon chef).
Moi je dis que si quelqu'un veut programmer il doit connaître le langage
et ne doit pas avoir peur de choses comme les pointeurs (qui n'ont
jamais mangé personne). Et que s'il ne comprend pas, il n'a qu'a mieux
apprendre le langage. C'est peut être en peu tranché comme avis, mais si
d'autres faisaient comme moi probablement on aurait du code mieux écrit.

> dc

ciao, Leo

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://forum.linux-gull.ch/pipermail/gull/attachments/20050928/e5c3333f/attachment.pgp>


More information about the gull mailing list