OVH Cloud OVH Cloud

Adresse d'un tableau

51 réponses
Avatar
candide
Bonjour,

Soit le programme suivant :

/*
* ---------------- adresseTableau.c -------------------
*/
#include <stdio.h>

int main(void)
{
int a[2] =3D { 100, 200 };

printf("%p\n%p\n", (void *) a, (void *) &a);

return 0;
}

/*
* -----------------------------------------------------------
*/

Il m'affiche deux valeurs identiques. Cette co=EFncidence d=E9pend-elle
exclusivement de l'impl=E9mentation ?

J'ai regard=E9 la norme et je ne vois rien qui permette de l'affirmer (=E0
la diff=E9rence de l'adresse d'une structure, cf. 6.7.2.1#13). Pourtant,
en consultant les archives de fclc, certains intervenants laissent
penser que oui. Pour clc, le discours est plus prudent mais aucune
r=E9ponse cat=E9gorique, comme si la question =E9tait mal pos=E9e.

La r=E9ponse la moins vague que j'aie pu trouver est celle de DMR sur
comp.std.c en 1999 qui dit :

/In the usual implementation the bit value of &a[0] and &a will be the
same,/

Comment faut-il interpr=E9ter ce /In the usual implementation/ ?

Merci pour toute clarification apport=E9e.

Candide

10 réponses

1 2 3 4 5
Avatar
Marc Boyer
On 2008-02-12, Vincent Lefevre <vincent+ wrote:
Dans l'article ,
Marc Boyer écrit:

On 2008-02-12, Antoine Leca wrote:
En clair, avec
char b[2] = { 100, 200 };
void* p = b; /* sans effet de conversion, d'après 6.2.5p27 */


Pardon, est-ce que tes doigts n'ont pas fourché sur le clavier.
Parce que dans ce que j'ai sous les yeux, 6.2.5p27, c'est un exemple
sur float* et const float *.


C'est le cas dans n1124 (basée sur le TC2) et ce dont parle Antoine
est le 6.2.5p26, mais dans n869 (dernier draft public de C99), ça
correspond bien. La confusion vient peut-être de là.


OK, merci.
Je travaille avec la version imprimée par Wiley, avec seulement
le TC1. Il y a décalage d'un numéro.

Marc
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)



Avatar
Marc Boyer
On 2008-02-12, Antoine Leca wrote:
Pour le cas des opérateurs d'égalité, il est aussi possible de comparer un
pointeur arbitraire (au hasard, &a !) avec un pointeur universel void*; dans
ton exemple cela imposerait un transtypage avec conversion de int* vers
void*, mais si on prend le cas peu différent de char b[2], on peut faire
abstraction de cette conversion supplémentaire. On en réduit le champ à
6.5.9p6, qui est le plus précis (que j'ai trouvé) que la norme puisse
t'offrir :
Two pointers compare equal if and only if [...] both are pointers to
the
same object (including a pointer to an object and a subobject at its
beginning) [...]

En clair, avec
char b[2] = { 100, 200 };
void* p = b; /* sans effet de conversion, d'après 6.2.5p27 */


AMHA, il y conversion en int* ici (6.3.2.1p3) puis int* -> void*.

on a
p == &b


Mais est-ce que 'p' pointe 'at its beginning' ?


De toutes les façons, je ne vois pas bien l'intérêt de chercher à savoir


Disons que c'est pour l'exercice ;-)


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

Avatar
Vincent Lefevre
Dans l'article ,
Marc Boyer écrit:

On 2008-02-12, Antoine Leca wrote:
On peut aussi imaginer une implémentation où les tableaux seraient
en fait des descripteurs de tableaux, en gros une structure
stockée «ailleurs», avec entre autres un pointeur vers les
véritables données. Dans ces conditions, &a retournerait l'adresse
de ce descripteur, qui serait incommensurable (sauf conversion)
avec les données elles-mêmes. Il est possible de glisser de tels
descripteurs /derrière/ le tableau dans une structure, par exemple
(6.7.2.1p15). Un des intérêts de ce genre d'implémentation serait
de pouvoir implémenter une vérification dynamique des bornes des
tableaux. Je n'ai pas vérifié en profondeur, mais je pense que
cela doit être conforme (moyennant une pelleté de restrictions
d'implémentations à documenter.)


Le problème, c'est que je vois pas comment ce genre d'implantation
pourra faire tourner un code de copie à base de memcpy:

int a[5]= { 0 , 1 , 2 , 3 , 4 };
int b[20];
memcpy(&b, &a, sizeof a );
assert( a[0] == b[0] );


Aucun problème puisque cette implémentation s'occupe de faire les
transformations nécessaires de façon à ce que sémantiquement, &a
pointe sur a[0].

car il va être difficile à memcpy (qui ne verra que le descripteur,
par conversion int[5]* en int* puis void* ) d'aller copier les vrais
valeurs.


Pour le &a, il y a juste conversion de int[5]* en void*, et je
suppose que c'est là où l'implémentation doit faire le changement
de représentation interne du pointeur.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


Avatar
Jean-Marc Bourguet
"Antoine Leca" writes:

En news:, Marc Boyer va escriure:
On pourrait peut-être imaginer un compilateur hypothétique qui
stoque 'quelque chose' au début d'un tableau, avant le premier
élément (si j'ai pas raté un truc).


Rigolo comme idée.
J'ai examiné plusieurs facettes (y compris la construction des structures,
6.7.2.1p13 en particulier, 6.2.5p20 ou 6.5.6p8), et je n'ai pas trouvé non
plus de motifs pour rejeter cela /a priori/. Il faudrait seulement des
versions spéciales pour == (6.5.9) ou sizeof (6.5.3.4) qui ferait
abstraction du « quelque chose ».


Je ne vois pas comment faire fonctionner quelque chose comme

int (*a)[5];
a = malloc(sizeof a);

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Vincent Lefevre
Dans l'article ,
Marc Boyer écrit:

On 2008-02-12, Antoine Leca wrote:
En clair, avec
char b[2] = { 100, 200 };
void* p = b; /* sans effet de conversion, d'après 6.2.5p27 */


AMHA, il y conversion en int* ici (6.3.2.1p3) puis int* -> void*.


Que vient faire ici le int* ? C'est un char*. Mais un char* et un
void* ont la même représentation:

[citation du draft n869]
[#27] A pointer to void shall have the same representation
and alignment requirements as a pointer to a character type.

on a
p == &b


Mais est-ce que 'p' pointe 'at its beginning' ?


La norme dit: "that points to the initial element of the array object".
C'est pareil, non?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


Avatar
Vincent Lefevre
Dans l'article ,
Jean-Marc Bourguet écrit:

"Antoine Leca" writes:

En news:, Marc Boyer va escriure:
On pourrait peut-être imaginer un compilateur hypothétique qui
stoque 'quelque chose' au début d'un tableau, avant le premier
élément (si j'ai pas raté un truc).


Rigolo comme idée.
J'ai examiné plusieurs facettes (y compris la construction des structures,
6.7.2.1p13 en particulier, 6.2.5p20 ou 6.5.6p8), et je n'ai pas trouvé non
plus de motifs pour rejeter cela /a priori/. Il faudrait seulement des
versions spéciales pour == (6.5.9) ou sizeof (6.5.3.4) qui ferait
abstraction du « quelque chose ».


Je ne vois pas comment faire fonctionner quelque chose comme

int (*a)[5];
a = malloc(sizeof a);


Euh... la variable a n'est qu'un pointeur (vers un tableau), non?
Je ne comprends pas cet exemple...

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)



Avatar
Jean-Marc Bourguet
Vincent Lefevre <vincent+ writes:

Dans l'article ,
Jean-Marc Bourguet écrit:

"Antoine Leca" writes:

En news:, Marc Boyer va escriure:
On pourrait peut-être imaginer un compilateur hypothétique qui
stoque 'quelque chose' au début d'un tableau, avant le premier
élément (si j'ai pas raté un truc).


Rigolo comme idée.
J'ai examiné plusieurs facettes (y compris la construction des structures,
6.7.2.1p13 en particulier, 6.2.5p20 ou 6.5.6p8), et je n'ai pas trouvé non
plus de motifs pour rejeter cela /a priori/. Il faudrait seulement des
versions spéciales pour == (6.5.9) ou sizeof (6.5.3.4) qui ferait
abstraction du « quelque chose ».


Je ne vois pas comment faire fonctionner quelque chose comme

int (*a)[5];
a = malloc(sizeof a);


Euh... la variable a n'est qu'un pointeur (vers un tableau), non?
Je ne comprends pas cet exemple...


Oops,

a = malloc(sizeof *a);

evidemment. Le probleme c'est que sizeof(*a) ne prend pas en compte la
place necessaire pour le quelque chose (il est garanti que sizeof(*a) = 5*sizeof(int)).

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org




Avatar
Antoine Leca
En news:, Jean-Marc Bourguet va escriure:
Je ne vois pas comment faire fonctionner quelque chose comme

int (*a)[5];
a = malloc(sizeof a);


malloc renvoit un pointeur vers le premier octet (byte) alloué, pointeur qui
a une forme « type malloc » permettant de localiser le descripteur afférent
(jusque là, rien de nouveau, quasiment toutes les implémentations de
malloc+free font cela) ; et le descripteur est celui d'un tableau de char de
taille [sizeof a] (histoire d'être compatible avec 6.2.5p27, même
représentation pour void* et char*).

La conversion de void* vers int(*)[5] va créer un « descripteur alias » avec
ce nouveau nouveau type, et retourner le pointeur converti, en l'occurence
un pointeur vers le descripteur (qui inclut donc la description du type, et
le pointeur vers les données).

Lequel pointeur est assigné à a, sans autre souci.


En gros, à chaque opération en C où l'utilisation des pointeurs permet
d'espérer normalement une opération transparente, tu vas avoir une
conversion induite, avec souvent création de descripteurs (et donc
probablement une sorte de ramasse-miettes pour détruire les alias).


C'est clair qu'au niveau des performances, le résultat se sera pas
comparable à icc :-). Mais bon, la cible ce serait plutôt genre Ada.


Antoine

Avatar
Vincent Lefevre
Dans l'article ,
Jean-Marc Bourguet écrit:

Vincent Lefevre <vincent+ writes:

Dans l'article ,
Jean-Marc Bourguet écrit:

"Antoine Leca" writes:

En news:, Marc Boyer
va escriure:
On pourrait peut-être imaginer un compilateur hypothétique
qui stoque 'quelque chose' au début d'un tableau, avant le
premier élément (si j'ai pas raté un truc).


Rigolo comme idée.
J'ai examiné plusieurs facettes (y compris la construction des
structures, 6.7.2.1p13 en particulier, 6.2.5p20 ou 6.5.6p8),
et je n'ai pas trouvé non plus de motifs pour rejeter cela /a
priori/. Il faudrait seulement des versions spéciales pour = > > > > (6.5.9) ou sizeof (6.5.3.4) qui ferait abstraction du «
quelque chose ».


Je ne vois pas comment faire fonctionner quelque chose comme

int (*a)[5];
a = malloc(sizeof a);


Euh... la variable a n'est qu'un pointeur (vers un tableau), non?
Je ne comprends pas cet exemple...


Oops,

a = malloc(sizeof *a);

evidemment. Le probleme c'est que sizeof(*a) ne prend pas en compte la
place necessaire pour le quelque chose (il est garanti que sizeof(*a) = > 5*sizeof(int)).


Mais maintenant, on n'a plus de tableau: a ne reste qu'un pointeur
(le tableau n'intervient qu'en tant que type). Je suppose que le
'quelque chose' au début d'un tableau dont parle Marc ci-dessus,
c'est uniquement pour les tableaux déclarés dans le source; sinon
on ne peut pas manipuler de tableau (on peut écrire *a, mais c'est
immédiatement converti en un pointeur ou utilisé par sizeof). De
toute façon, le malloc ne sait pas a priori que les données vont
correspondre à un tableau et ne peut donc pas ajouter ce quelque
chose.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)





Avatar
Vincent Lefevre
Dans l'article <20080212142746$,
Vincent Lefevre <vincent+ écrit:

Mais maintenant, on n'a plus de tableau: a ne reste qu'un pointeur
(le tableau n'intervient qu'en tant que type).


Ah, comme le dit Antoine, le descripteur peut être créé (réellement
"créé") lors de la conversion du pointeur. Dans ce cas, il n'est pas
forcément situé avant le tableau.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

1 2 3 4 5