OVH Cloud OVH Cloud

Différence de résultat entre compilateurs

291 réponses
Avatar
YannicK
Bonjour,

éternel débutant en C pour mon plaisir, je me permets de venir vous
demander quelques éclaircissements sur une situation que je n'arrive pas
à comprendre :

J'utilise le cours en ligne spécial "grand débutant" du "site du zéro" :
<http://www.siteduzero.com/tutoriel-3-14189-apprenez-a-programmer-en-c.html>

Je réalise les exercices du cours dans deux environnements différents :
- sous windows vista avec l'IDE visual C++ 2008 express
- sous linux ubuntu 9.04 avec gcc

J'ai écrit un programme dans le cadre des exercices proposés sur les
tableaux par ce cours en ligne. Le fichier en question peut être
téléchargé ici :
< http://dl.free.fr/to7PFReLM/tableau.c>

Ce qui m'étonne, c'est que j'arrive à compiler sans difficulté ce code
sous Linux, et que le programme se comporte exactement comme je le
souhaite. Par contre, sous Windows, impossible de compiler, l'IDE me
renvoie 42 erreurs et 31 avertissements !!! La plupart des erreurs
semblent être liées aux variables. Par exemple :
"erreur de syntaxe : absence de ';' avant 'type'"
"identificateur non déclaré"

Or, j'ai beau lire et relire mon code, les variables me sembles toutes
déclarées correctement et il ne manque à mon sens pas de ";" en fin
d'instructions. De plus, comme je le disais au début, le même code se
compile sans aucune erreur sous Linux ...

Alors, comment expliquer que deux compilateurs réagissent aussi
différemment, et où et mon erreur ?

Merci par avance du temps que vous pourrez me consacrer,



--
YannicK
yann801 *arobase* yahoo *point* fr
yann801 *at* yahoo *dot* fr

10 réponses

Avatar
Richard Delorme
Le 16/09/2009 00:52, a écrit :
Bsr/jr,

Je commence avec les pointeurs et je voudrais comprendre le code de ce
tutorial :
http://www.ltam.lu/Tutoriel_Ansi_C/

Je ne sais pas comment l'auteur à organiser ces liens html mais je ne
peux pas copier-coller le lien exact de la page ou se trouve le
code...pour faire bref, il s'agit de l'exercice 9.5 dans le chapitre
des pointeurs.

Il y a diverses questions dans à l'intérieur du code ci-dessous :

#include<stdio.h>

int main(void)
{
int TabA[] = { 31, 62, 17, 28, 45, 62, 34, 22, 62 } ;
int *p1 = TabA ;
int *p2 = TabA ;
nbr = 62 ;



for ( p1 = TabA ; p1< TabA+n ; p1++ )
{
*p2 = *p1 ;
if ( *p2 != nbr )
p2++ ;
}



Question 1:

A ce niveau, si je boucle avec p2, les valeurs renvoyees sont :
("n" n'a pas été redimensionné)

{ 31, 17, 28, 45, 34, 22, 62, 22, 62 }

printf("np2: n" ) ;
for ( p2 = TabA ; p2< TabA+n ; p2 ++ )
printf("%dt", *p2 ) ;

Les valeurs renvoyees sont toujours au nombre de 10 comme lors de
leur initialisation
mais a partir de l'indice 6 soit 22, je ne comprends pas les valeurs
que je retrouve
après cet indice soit 62, 22, 62.



Pourtant elles sont logiques. Relis bien ce que fait la boucle que j'ai
laissé ci-dessus pour comprendre.


/* Questions 2:

printf("nTaille de P1 divise par int : %dn", sizeof(p1)/4) ;

- Pourquoi sizeof(p1) renvoie 1 ?



sizeof est un opérateur comme +, -, etc. et les parenthèse ne sont pas
une obligation. Ici tu peux écrire sizeof p1. Avec un type, il faut par
contre maintenir les parenthèses (opérateur de cast) : sizeof (int).
Le fait que sizeof soit un opérateur et non une fonction est important,
car il va fonctionner non pas en fonction de la valeur qu'il reçoit,
mais en fonction du type, et renvoyer la taille de ce type. Ici p1 est
un pointeur et la taille d'un pointeur est 4 chez toi.

--- alors que sizeof(TabA)/4), renvoie 9 ?



Tab4 est un tableau et sa taille est son nombre d'éléments x taille d'un
élément.

--- en fait sizeof ne fonctionne pas avec les pointeurs ???



Si puisqu'il renvoie la taille du pointeur.

--- seulement il y a un débat entre ceux qui disent que les tableaux
sont des pointeurs et ceux qui ne sont pas d'accord avec ça et
qui manquent d'arguments.



Là tu as une des différences entre un tableau et un pointeur, leur
taille est différente. La confusion vient du fait que TabA à la valeur
d'un pointeur et qu'il fonctionne souvent comme un pointeur

/* Questions 3:

Je ne comprends pas comment TabA qui a une valeur de renvoie avec
sizeof identique
tout au long du programme (normal ce n'est pas un pointeur :) ) et n
qui dans sa valeur
initiale est 9 et sa valeur volontairement modifiée renvoyée par n > p2 - TabA : 6 ...
ALORS QUE p2 sur ma machine a une valeur identique a TabA (chez moi
591036) au debut du déroulement
du programme mais qui est modifiée à partir de "Juste pour info 3" et
qui donne (chez moi) : 591060 alors
la question est comment est ce que dans les boucles correspondantes
591060< 591036 + 6 ???



C'est l'arithmétique des pointeurs. (TabA + n) donne la valeur du
pointeur vers le nième élément de TabA. En valeur tu as donc :
591060 = 591036 + (6 * 4).


Au tout début du programme : le second argument de la boucle est p1<
TabA + n soit
sur mon système : 591036< 591036 + 9 .
Là, je trouve que c'est cohérent mais avec p2, j'ai du mal à
comprendre.



C'est toujours l'arithmétique des pointeurs. p2 est un pointeur sur un
int, (p2 + n) est un pointeur vers le nième int après p2.


Je dois aussi avouer que ces nombre 591036, 591060 ne me parlent pas
beaucoup. Je crois il s'agit de l'affichage
avec une valeur entier d'une adresse dans le buffer. C'est unique à un
instant t a ce qui est dans la mémoire du système.
Par curiosité, s'agit-il de heap ou ou stack ?



Le langage C n'a pas de notion de tas ou de pile. Ça dépend de ton
système. Ici c'est sans doute sur la pile de ton programme.

--
Richard
Avatar
-ed-
On 16 sep, 00:52, ""
wrote:

Il y a diverses questions dans à l'intérieur du code ci-dessous :

#include <stdio.h>

int main(void)
{
        int TabA[] = { 31, 62, 17, 28, 45, 62, 34, 22, 62 } ;
        int *p1 = TabA ;
        int *p2 = TabA ;
        int n ;
        int nbr ;

        printf("nnEcrire un programme qui lit un entier nbr et un rayon
d'entiers TabA n"
        "du type int au clavier et élimine toutes les occurrenc es de nbr dans
TabA n"
        "en tassant les éléments restants. Le programme utili sera n"
        "les pointeurs p1 et p2 pour parcourir le rayon.n") ;

        n = sizeof(TabA) / sizeof(int) ;



n est initialisé ici. OK ?

Nota, cette expression est correcte, mais pas idiomatique. Je préfère
nettement :

n = sizeof TabA / sizeof *TabA ;

qui est indépendante du type...

Nota : *TabA est une forme simple de *(TabA + 0) qui est une autre
forme de TabA[0]. Personnellement, je vais au plus simple...

Évidemment, ça ne fonctionne que sur les tableaux et pas sur le
pointeurs...


        /* code intermédiaire pour comprendre le déroulement du prg */
        printf("nnnUST FOR INFO 1 n(juste apres l'affectation et
l'initialisation des valeurs et variables) : n" ) ;
        printf("------------------------------------------------- --------
n") ;
        printf("nTaille de int : %dn", sizeof(int)) ;
        printf("nnn = %dtp1 = %dtp2 = %dtTabA = %dn ", n, p1, p2,
TabA) ;



Incorrect. Le bon formateur pour afficher une adresse (TabA a pour
valeur et type l'adresse du premier élément du tableau nommé TabA), o n
doit utiliser "%p" et le cast (void *) :

printf ("nnn = %dtp1 = %ptp2 = %ptTabA = %pn", n, (void *)
p1, (void *) p2, (void *) TabA);

mais il est rarement utile de chercher à afficher une adresse.
Admettons ici un intérêt pédagogique. Attention, le format d'affichag e
dépend de l'implémentation. Il est souvent en hexadécimal...


        /* Reprise du programme */

        printf("nn") ;

        printf("Affichage du rayon de valeurs int non modifie : nn") ;

        for ( p1  ;  p1 < TabA+n  ;  p1++ )



Ceci n'a pas de sens. Soit on initialise p1 en lui donnant une valeur,
soit on ne fait rien :

for ( ; p1 < TabA+n ; p1++ )


                printf("%dt", *p1) ;

        /* code intermédiaire pour comprendre le déroulement du prg */
        printf("nnJUST FOR INFO 2 n(apres l'affichage des vale urs avec le
pointeur p1) : n" ) ;
        printf("------------------------------------------------- --------
n") ;
        printf("nnn = %dtp1 = %dtp2 = %dtTabA = %dn ", n, p1, p2,
TabA) ;

        /* Reprise du programme */

        printf("nnEntrez un entier a supprimer : n") ;
        nbr = 62 ;
        printf("...n") ;
        printf("Le nombre est : %d nn", nbr) ;

        for ( p1 = TabA  ;  p1 < TabA+n  ;  p1++ )
         {
                *p2 = *p1 ;
                if ( *p2 != nbr )
                        p2++ ;
        }

        /* code intermédiaire pour comprendre le déroulement du prg */
        printf("nnJUST FOR INFO 3 n(apres la recherche de la v aleur a
supprimer avec les pointeur p1 et p2) : n"
        "et apres l'affectation du tableau sans la valeur dans p2 .n") ;
        printf("------------------------------------------------- --------
n") ;
        printf("nnn = %dtp1 = %dtp2 = %dtTabA = %dn ", n, p1, p2,
TabA) ;

        /***************************************************

        Question 1:

        A ce niveau, si je boucle avec p2, les valeurs renvoyees sont :
        ("n" n'a pas été redimensionné)



dimensionné n'a pas de sens. Si tu veux dire initialisé, oui, n a ét é
initialisé (déjà mentionné au-dessus). Par contre, il faudrait le
modifier, car la taille utile du tableau a changé. Il aurait fallu le
diminuer de 1 à chaque fois qu'une valeur a été retirée du tableau.
Cet exemple de code est particulièrement et inutilement complexe.
L'usage en pédagogie de base est de ne traiter qu'un seul sujet à la
fois...


        { 31, 17, 28, 45, 34, 22, 62, 22, 62 }

        printf("np2: n" ) ;
        for ( p2 = TabA  ;  p2 < TabA+n  ;  p2 ++ )
                printf("%dt", *p2 ) ;

        Les valeurs renvoyees sont toujours au nombre de 10 comme lors de
leur initialisation



Oui, car n n'a pas été modifié.

        mais  a partir de l'indice 6 soit 22, je ne comprends p as les valeurs
que je retrouve
        après cet indice soit 62, 22, 62.



Ce sont les anciennes valeurs du tableau qui n'ont pas été modifiées.
L'action du code de 'suppression' a simplement été de recopier le
valeurs inchangée à un nouvel enplacement :

Au début :

31 62 17 28 45 62 34 22 62

'suppression' du premier '62' : il est remplacé par 17

31 17 17 28 45 62 34 22 62

puis l'ancien 17 est remplacé par 28 :
31 17 28 28 45 62 34 22 62
etc.
31 17 28 45 45 62 34 22 62

on retombe sur un 62, il est donc ignoré ('supprimé'), et c'est donc
le 34 qui prend la place de l'ancien 45 :

31 17 28 45 34 62 34 22 62

et un 22 qui remplace le 2ème 62 :

31 17 28 45 34 22 34 22 62

Les valeurs 34, 22 et 62 de la fin sont simplement les anciennes
valeurs du tableau initial qui n'ont pas été modifiées. Mais comme on
a supprimé 3 '62', il faut retirer 3 à n (9) qui vaut donc maintenant
6. La boucle d'affichage ne montre alors que les valeurs utiles du
nouveau tableau :

31 17 28 45 34 22



        ***************************************************/

        /* Reprise du programme */

        n = p2 - TabA ;

        printf("nnAffichage du nouveau rayon de valeurs int : nn") ;

        for ( p2 = TabA  ;  p2 < TabA+n  ;  p2++ )
                printf("%dt", *p2) ;

        /* code intermédiaire pour comprendre le déroulement du prg */
        printf("nnJUST FOR INFO 5 n(apres l'affichage du resul tat avec
p2) : n"
        ""n" a ete redimensionne et p2 remis au debut du rayon n") ;
        printf("------------------------------------------------- --------
n") ;
        printf("nnn = %dtp1 = %dtp2 = %dtTabA = %dn ", n, p1, p2,
TabA) ;

        /* Reprise du programme */

        printf("nn") ;

        return 0 ;

}

/* Questions 2:

printf("nTaille de P1 divise par int : %dn", sizeof(p1)/4) ;



Que signifie ce '4' ? Si c'est la taille d'un int sur ta machine,
mieux vaux mettre sizeof (int), comme ça, c'est portable...

- Pourquoi sizeof(p1) renvoie 1 ?



Tu veux probablement dire 4 ou alors il s'agit de sizeof(p1)/4.
Probablement parce que sur ta machine, la taille d'un pointeur est la
même que la taille d'un int. C'est anecdotique et sans intérêt...


--- alors que sizeof(TabA)/4), renvoie 9 ?



Encore une fois, il ne fait pas utiliser 4, mais sizeof (int) ou
mieux, comme je l'ai expliqué au-dessus, sizeof *TabA.

Ce mécanisme calcule le nombre d'éléments en se basant simplement sur
la définition que donne le C d'un tableau :

Un tableau est une séquence d'éléments identiques consécutifs en
mémoire.

La taille T est donc la taille d'un élément E x le nombre d'élément s
N :

T = E x N

Il n'est donc pas très difficile d'en déduire que le nombre d'éléme nts
est donc :

N = T / E

T est la taille du tableau : sizeof TabA
E est la taille d'un élément : sizeof *TabA

D'où l'expression C :

n = sizeof TabA / sizeof *TabA;

--- en fait sizeof ne fonctionne pas avec les pointeurs ???



Si mais pas comme tu le crois. Il donne la taille du pointeur, c'est
tout. Un pointeur n'est pas un tableau.

--- seulement il y a un débat entre ceux qui disent que les tableaux
sont des pointeurs et ceux qui ne sont pas d'accord avec ça et
qui manquent d'arguments.



Un pointeur n'est pas un tableau. Point. Y'a rien à argumenter. Les
définitions n'ont rien à voir.

De même, un vélo n'est pas une banane. Faut-il argumenter ?

/* Questions 3:

Je ne comprends pas comment TabA qui a une valeur de renvoie avec
sizeof identique
tout au long du programme (normal ce n'est pas un pointeur :) ) et n
qui dans sa valeur
initiale est 9 et sa valeur volontairement modifiée renvoyée par  n =
p2 - TabA : 6 ...
ALORS QUE p2 sur ma machine a une valeur identique a TabA (chez moi
591036) au debut du déroulement
du programme mais qui est modifiée à partir de "Juste pour info 3" et
qui donne (chez moi) : 591060 alors
la question est comment est ce que dans les boucles correspondantes
591060 <  591036 + 6 ???



J'ai un peu du mal à comprendre ta question. De toutes façons, je
trouve cet exercice horriblement complexe et confusant. Il est fait un
usage artificiel et non justifié des pointeurs qui ne fait que
compliquer quelque chose de simple...

L'expression

n = p2 - TabA;

met à jour la valeur de n, par ce que, et ce n'est visiblement pas dit
dans le cours, la différence entre 2 pointeurs sur un même tableau
donne un nombre d'éléments... Ça ne s'invente pas, c'est une des
définitions du langage C... C'est une des conséquences de
l'arithmétique des pointeurs.

TabA est l'origine du tableau (ton cours aurait du te dire que la
valeur et le type du nom du tableau est l'adresse du premier élément
de ce tableau).

p2 est l'adresse qui suit le dernier élément copié (p1 lit, p2 écri t)

p2 - TabA est donc le nombre d'éléments de nouveau tableau (ici, 6).
Attention, la taille réelle du tableau reste inchangée (9 éléments) .
C'est la 'taille utile' qui a été modifiée : normal, on a
'supprimé' (en fait, ignoré) 3 éléments.

Tout ceci aurait été bien plus clair en utilisant les indices... Il
n'y a aucune raison dans un cours d'initiation au C, de compliquer la
compréhension avec ces pointeurs...

Au tout début du programme : le second argument de la boucle est p1 <
TabA + n soit
sur mon système : 591036 <  591036 + 9 .
Là, je trouve que c'est cohérent mais avec p2, j'ai du mal à
comprendre.

Je dois aussi avouer que ces nombre 591036, 591060 ne me parlent pas
beaucoup. Je crois il s'agit de l'affichage
avec une valeur entier d'une adresse dans le buffer. C'est unique à un
instant t a ce qui est dans la mémoire du système.



Oui, et comme je l'ai déjà dit, c'est inutile. La vrai abstraction
compréhensible par tous est l'indice d'un, tableau.

Par curiosité, s'agit-il de heap ou ou stack ?



En C, il n'y a ni heap, ni stack. Il y a 3 'classes' mémoire :

http://www.bien-programmer.fr/notes.htm#donnees
Avatar
Richard Delorme
Le 15/09/2009 16:22, Gabriel Dos Reis a écrit :

| file_t pourrait rester une structure opaque, ce qui en ferait un type
| abstrait non contrôlable par l'utilisateur. Bref ça changerait peu la
| situation actuelle, sauf la possibilité d'éviter l'inclusion de
|<stdio.h>

pouvoir voudrais-tu insister que FILE soit une structure?



Premièrement, à cause de sa définition dans la norme. FILE est un
"object type" supposé contenir tout un tas de chose (buffer, pointeur
dans le fichier, etc.). Même si FILE pourrait être un entier codant tout
ça de manière magique (pour un buffer, je me demande bien comment), ou
un tableau, ou je ne sais quoi encore (mais pas une macro, ni une
fonction ni un type incomplet), la structure est la manière la plus
naturelle d'enregistrer tout ça.
Deuxièmement parce qu'une structure peut très bien être opaque, c'est à
dire utilisable uniquement à travers de fonctions, comme actuellement
pour FILE.
Troisièmement, parce que c'est souvent (toujours ?) une structure en
pratique.

|<stdio.h> ici n'est qu'un exemple, et sans doute pas le meilleur. Bien
| sûr les compilateurs ont leur part de responsabilité dans le temps de
| compilation, et il existe des techniques bien connues (en-têtes
| précompilés par exemple) pour accélérer leur performance. Néanmoins je
| pense que les programmeurs ont aussi leur part de responsabilité et il
| est souvent possible de fournir, à fonctionnalité équivalente, un code
| plus rapide à compiler.

La premiere responsabilite du programmeur devrait d'etre d'ecrire des
programmes simples et corrects. C'est deja suffisamment dur comme cela.



Ecrire des programmes simples et corrects doit souvent suffire à
répondre à mes exigences.

C'est non-professionnel de chercher des elaborations sur des details
imagines sans evidence d'impactes reels.



Installe une Gentoo, tu vas voir si le temps de compilation n'est pas
sans impacts réels.

--
Richard
Avatar
bpascal123
> > - Pourquoi sizeof(p1) renvoie 1 ?

Tu veux probablement dire 4 ou alors il s'agit de sizeof(p1)/4.
Probablement parce que sur ta machine, la taille d'un pointeur est la
même que la taille d'un int. C'est anecdotique et sans intérêt...





Il s'agit bien de sizeof(p1), j'avais oublié d'enlevé '/4', c'est
pourquoi je ne comprenais pas le résultat (premier contact avec les
pointeurs et je ne sais pas vraiment à quoi m'attendre).

En fait, si je commence à comprendre, avec les pointeurs, dans un
tableau de valeurs, on ne parle pas d'indices mais d'adresses?

L'indice d'un tableau "classique" commence souvent à 0 alors que
l'indice d'un pointeur sur un tableau commence à une adresse exprimée
sous forme hexadécimale avec par exemple 0x001 pour la première valeur
et 0x002 pour la seconde. Les valeurs hexadécimales sont bien les
emplacements mémoire?

Merci,
Pascal
Avatar
Jean-Marc Bourguet
Marc writes:

Gabriel Dos Reis wrote:

| Techniquement il est très rare que FILE soit un véritable type opaque,
| car pour implémenter les macros getc()et putc(), on a besoin des
| éléments de la structure...



Je ne crois pas que getc et putc soient forcément des macros, c'est juste
une possibilité.



L'intérêt d'avoir fgetc et getc, fputc et putc, c'est la lattitude donnée à
getc et putc quand elles sont implémentées comme macro de pouvoir évaluer
plusieurs fois leurs arguments.

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Jean-Marc Bourguet
(Marc Espie) writes:

Il y a meme certaines bibliotheques qui te mettent des valeurs rigolotes
en hexa dans la memoire apres un free. je pense en particulier au
classique: 0xDEADBEEF



0xBADC0DE n'est pas mal (mais commencant par un 0 et finissant par un
nombre pair, a un peu plus de chance d'arriver par hasard et pose moins de
problèmes). J'avais vu une liste quelque part -- petite recherche, je
trouve ceci qui y ressemble http://nedbatchelder.com/text/hexwords.html

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
-ed-
On 16 sep, 12:57, ""
wrote:
En fait, si je commence à comprendre, avec les pointeurs, dans un
tableau de valeurs, on ne parle pas d'indices mais d'adresses?



Si on veut...

L'indice d'un tableau "classique" commence souvent à 0 alors que
l'indice d'un pointeur sur un tableau commence à une adresse exprimée



Dans ce cas, on ne parle pas d'indice, mais d'adresse...

sous forme hexadécimale avec par exemple 0x001 pour la première valeu r
et 0x002 pour la seconde. Les valeurs hexadécimales sont bien les
emplacements mémoire?



Le fait que la valeur soit exprimée en hexadécimale est juste pour
rappeler que ce n'est pas pour les débutants ! Une valeur interne est
toujours codée en binaire sur nos machines 'binaires'...

La valeur d'une adresse dépend de l'implémentation et des conditions
courantes. Par exemple, un tableau peut très bien démarrer à une
adresse 0x00FF1234 ou 0XDEADBEEF, peu importe. de toutes façons, sur
les machines modernes, cette adresse est juste une valeur (une
référence) qui n'a aucune signification "physique".

Il ne faut pas y attacher une importance particulière. Les pointeurs
permettent de manipuler 'magiquement' des adresses et surtout
d'accéder aux données pointées (parce qu'ils sont typés), mais on a
pas à s'intéresser à la valeur elle-même du pointeur. Elle ne conce rne
que l'environnement d'exécution. Par contre on veillera à ce que cette
valeur soit toujours valide.

http://www.bien-programmer.fr/notes.htm#pointeurs
Avatar
espie
In article ,
-ed- wrote:
On 16 sep, 12:57, ""
wrote:
En fait, si je commence à comprendre, avec les pointeurs, dans un
tableau de valeurs, on ne parle pas d'indices mais d'adresses?



Si on veut...

L'indice d'un tableau "classique" commence souvent à 0 alors que
l'indice d'un pointeur sur un tableau commence à une adresse exprimée



Dans ce cas, on ne parle pas d'indice, mais d'adresse...

sous forme hexadécimale avec par exemple 0x001 pour la première valeur
et 0x002 pour la seconde. Les valeurs hexadécimales sont bien les
emplacements mémoire?



Le fait que la valeur soit exprimée en hexadécimale est juste pour
rappeler que ce n'est pas pour les débutants ! Une valeur interne est
toujours codée en binaire sur nos machines 'binaires'...



mort de rire ;) C'est mignon. Nan, c'est en hexa parce que ca donne
plus d'information (en terme d'alignement sur le bus, voire sur les pages
memoire). Et avec l'habitude, c'est plus lisible. (mais bon, tu le sais,
je dis juste ca pour nos lecteurs).

Il y a meme certaines bibliotheques qui te mettent des valeurs rigolotes
en hexa dans la memoire apres un free. je pense en particulier au
classique: 0xDEADBEEF
Avatar
Pierre Maurette
Marc Espie, le 16/09/2009 a écrit :

[...]

Il y a meme certaines bibliotheques qui te mettent des valeurs rigolotes
en hexa dans la memoire apres un free. je pense en particulier au
classique: 0xDEADBEEF



Mouarf. Ça me rappelle les petits jeux sur les premières calculatrices
programmables qui écrivaient des trucs marrant quand on les lisait en
retournant la calculette.

--
Pierre Maurette
Avatar
Marc
Jean-Marc Bourguet wrote:

| Techniquement il est très rare que FILE soit un véritable type opaque,
| car pour implémenter les macros getc()et putc(), on a besoin des
| éléments de la structure...



Je ne crois pas que getc et putc soient forcément des macros, c'est juste
une possibilité.



L'intérêt d'avoir fgetc et getc, fputc et putc, c'est la lattitude donnée à
getc et putc quand elles sont implémentées comme macro de pouvoir évaluer
plusieurs fois leurs arguments.



Je sais, mais rien n'oblige à effectivement les implémenter comme des
macros accédant aux champs de FILE. Comme ça on peut éviter d'inclure la
disposition de FILE dans l'ABI. Après c'est une question de priorités,
veux-tu gagner quelques microsecondes, ou préfères-tu laisser à l'OS des
chances d'être amélioré tout en laissant tourner le programme sans
recompilation ? Les deux se défendent, suivant les usages.