[gull] Types : [was: Php/MsSQL obsoletes?]

Daniel Cordey dc at mjt.ch
Thu Sep 29 13:43:19 CEST 2005


On Wednesday 28 September 2005 23:00, JM Nunes wrote:

> ou dynamiquement (Pyhton, Perl -je crois), à l'exécution.

Ben oui... les langages interpretes ne passent pas par la phase de 
compilation :-)

> Ainsi en C c'est
> 	char* x = "123"
> et en Ocaml c'est
> 	let x = "123"
>
> -"strongly typed"...

Que veux-tu dire par la... ?

>
> *************** en C ****************
> main () {
> char* x = "123";
>    printf ("x=%i"; x);
> }
> ************
> compilé et exécuté résulte en:
> ./a.out
> x=134513860
>
> *************** en Ocaml ********************
> $ ledit ocaml
>          Objective Caml version 3.08.3
>
> # let x = "123";;
> val x : string = "123"
> # Printf.printf "x=%i" x;;
> This expression has type string but is here used with type int
> #
> ***********************
> **************** en Python **********************
> $ python
> Python 2.3.5 (#2, May  4 2005, 08:51:39)
> [GCC 3.3.5 (Debian 1:3.3.5-12)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>
>  >>> x = "123"
>  >>> print 'x=%i' % x
>
> Traceback (most recent call last):
>    File "<stdin>", line 1, in ?
> TypeError: int argument required
>
> ******************
> et donc C est plus faiblement typé que Ocaml et Python.

Ce ne sont pas dut tout les memes choses. Je crois que la confusion viend du 
fait que les chaines de caracteres sont manipulees a l'aide de pointeurs, 
alors que dans tous les autres langages (aurais-je oublier un langage qui 
fasse pareil ?)  il existe un type "string", totalement absent en C. Un 'char 
*' n'est pas un type "tring"; ce n'est qu'un vulgaire pointeur sur des 
valeurs de 1 byte !!! A ce titre, on ne compare pas du tout la meme chose. On 
peut discuter longtemps de l'absence d'un type de base "string" en C... il se 
trouve que c'est comme ca, que c'est tres simple mais c'est tout. Idealement, 
d'ailleurs, on devrait ecrire :

	const char x[] = "123";

Mais ca n'a pas beaucoup d'importance...

Ce qui fait que toute cette discussion concernant les chaines de caractere est 
biaisee. Un pointeur n'est qu'un "symbole" contenant une adresse. A ce titre, 
un "char *" ou un "double *" ne sont pas pareils. Tous les pointeurs ont une 
"empreinte" identique en memoire, mais les operations arithmetiques sur 
chacun d'eux ne sont pas identiques ! Exemple :

int main(int argc, char *argv[])
{
    char *pc;
    double *pd;

    char c = 'X';
    double d = 1.234;

    pc = &c;
    pd = &d;

    printf("pc\t: 0x%x\npc + 1\t: 0x%x\npd\t: 0x%x\npd + 1\t: 0x%x\n", pc, pc 
+ 1, pd, pd + 1);
    printf("pc delta\t: %d\npd delta\t: %d\n", pc + 1 - pc, pd + 1 - pd);
}



pc      : 0xbfffefef
pc + 1  : 0xbfffeff0
pd      : 0xbfffefe0
pd + 1  : 0xbfffefe8
pc delta        : 1
pd delta        : 1

On voit que chaque pointeur est incremente en fonction du "type" sur lequel il 
pointe. pc est incremente de 1 byte, alors que pd est incremente de 8 bytes !

Les pointeurs sont donc aussi "fortement" types, et le traitement des chaines 
de caracteres est une utlisation particuliere d 'un type de pointeur. Une 
chaine de catactere n'est en aucun cas un type en C; ce n'est qu'une suite de 
bytes en memoire, conventionnellement terminee par un carcatere NULL.


> Essayons maintenant
> ***************** C ****************
>   main(){
> int x = 123;
> 	printf ("x=%s",x);
> }
> **************
> le résultat est
> $ ./a.out
> Segmentation fault

Ici, normal... c'est plutot la librairie C qui est coupable. Elle "balaie" la 
chaine de caractere representant le format, afin de determiner ce qu'elle 
doit recuperer comme argument dans la liste. Sur la base du %s, elle 
considere que le deuxieme argument de la fonction est un pointeur, elle en 
prend donc la valeur et essaie de lire les byte a cette adresse... 
Naturellement, avec une valeur de '495051', on a toute les chances de genere 
un 'segmentation fault'; cette adresse ne faisant certaienement pas partie 
des pages de la zone data du process...

Comme dans Ocaml, c'est donc une mauvaise definition de format d'impression 
qui est a mettre en cause, plutot que le type.

> ************ Python ****************
>
>  >>> x=123
>  >>> print 'x=%s' % x
>
> x=123
> ******************
>
> D'où Python est plus faiblement typé que Ocaml.

Absolument pas ! C'est exactement le contraire... en Python, chaque type est 
un objet, or, un objet 'int' a une methode __str__() definie par defaut... et 
cest cette methode qui est appelee automatiquement par le fait de la 
definition '%s' dans le format d'impression. Pour vous en convaincre, il vous 
suffit de creer une classe quelqconque, sans methode __str__. En essayent 
d'imprimer un instance de votre objet avec le format "%s", vous aurez une 
exeption due au fait que l'interpreteur ne trouve pas de methode __str__ 
associee a cet objet ! Ce qui est parfaitement logique... meme elegant :-)

On voit bien qu'il n'est pas necessaire de discuter pour savoir si un langage 
est plus "type" qu'un autre. Cela n'amene rien de plus. Il suffit de bien 
comprendre comment chaque langage manipule ses types et ses donnees, d'en 
connaitres les limites et les contraintes. A partir de la, on peut programmer 
proprement.

> <troll>
> Si toutefois on cherche le langage le moins mauvais pour exprimer tout
> algorithme ---i.e., *le* langage de programmation générique--- on finit
> par trouver Ocaml. Mais je vous laisse le temps de le découvrir...
> </troll>

Pourquoi pas :-) Chaque lanagage poursuit un objectif prioritaire. Certains 
sont plsu adaptes que d'autres pour certaines taches, mais aucun langage ne 
peut pretendre tout faire mieux que tous les autres. Si aucun langage ne vous 
satisfait, ecrivez le votre ! C'est ce que les auteurs de tous les langages 
dont on parle on fait... sauf Ada et PL/1 (entre autre) :-)

dc



More information about the gull mailing list