Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

2 3 4 5 6
Avatar
Vincent Lefevre
Dans l'article <foulhq$av3$,
Antoine Leca écrit:

En news:20080212235426$, Vincent Lefevre va
escriure:
Je rappelle ce qu'on cherchait à montrer:

(void*) a == (void*) &a

Comme l'égalité ci-dessus est équivalente à

&a[0] == &a


Pas d'accord.
En supposant int a[XXX], le pointeur de gauche est de type int*, celui de
droite de type int(*)[XXX], je n'ai pas trouvé dans la norme de texte
définissant explicitement le comportement de l'opération == ci-dessus dans
un tel cas.


Ah oui, j'avais oublié les contraintes.

Mais alors le "(including a pointer to an object and a subobject at
its beginning)" de 6.5.9 n'est-il pas contraire aux contraintes? Je
vois mal le sens de cette parenthèse.

Cela étant, il n'est pas nécessaire de simplifier pour pouvoir
appliquer 6.5.9, bien au contraire. Seulement, savoir que les
pointeurs convertis soient égaux au sens de l'opération == n'apporte
pas beaucoup d'information sur les pointeurs avant conversion.


Je crois que la principale question était de savoir s'ils pointaient
vers les mêmes données, i.e. s'ils étaient égaux (après les
conversions nécessaires). Je pense que l'utilité d'un pointeur sur un
tableau est essentiellement de faire de l'arithmétique de pointeurs
quand on a un tableau de tableaux, mais on se ramène au final à un
pointeur vers un élément après une conversion. Ça m'étonnerait que la
représentation interne du pointeur ait une réelle utilité en pratique.

--
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
Antoine Leca
En news:, Marc Boyer va escriure:
On 2008-02-12, Antoine Leca wrote:
En news:, Marc Boyer va
escriure:
Je suppose que, formellement, il faut faire le cast en void* avant
un appel à memcpy, c'est ça ?


Non non, l'objet des prototypes c'est justement de rajouter la
conversion *sans* que le programmeur soit obligé de rajouter les
hideux transtypages (casts).


Non, je me suis demandé un instant si la conversion en void* n'était
pas implicite. Et comme je n'ai pas réussi à la retrouver dans la
norme, je me suis dit que j'avais raté un truc.


6.5.2.2 Function calls
[#7] If the expression that denotes the called function has a type
that does include a prototype, the arguments are implicitly
converted, as if by assignment, to the types of the corres-
ponding parameters, taking the type of each parameter to be
the unqualified version of its declared type. [...]

Évidemment, le précédent paragraphe #6 dit que s'il n'y a pas de prototypes,
il n'y a plus cette conversion implicite et badaboum.

[...] The ellipsis notation in a function prototype declarator
causes argument type conversion to stop after the last declared
parameter. The default argument promotions are performed on
trailing arguments.

Donc plus de conversions ! Raison (pas la seule) pour laquelle 'candide' a
eu bien raison, au début de l'enfilade, d'écrire

printf("%pn%pn", (void *) a, (void *) &a);


Antoine



Avatar
Vincent Lefevre
Dans l'article <forq9l$l89$,
Antoine Leca écrit:

En 2004, le sujet est ressorti une fois de plus
(http://groups.google.com/group/comp.std.c/browse_thread/thread/5533e861f117
55e0); il est intéressant de noter que la position de Larry (en réponse à
Dan Pop) est devenue moins nette...


Je me demandais pourquoi l'URL ne fonctionnait pas... La voici sur une
seule ligne (sinon évidemment, mon lecteur de news n'a pas l'idée de
deviner qu'il fallait regarder le début de la ligne suivante):

http://groups.google.com/group/comp.std.c/browse_thread/thread/5533e861f11755e0

--
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 <founia$gtv$,
Antoine Leca écrit:

Donc plus de conversions ! Raison (pas la seule) pour laquelle 'candide' a
eu bien raison, au début de l'enfilade, d'écrire

printf("%pn%pn", (void *) a, (void *) &a);


Hmm... Je m'aperçois que dans MPFR, on a du code du genre:

mpfr_clears (s, u, v, w, (void *) 0);

où la fonction attend des arguments du type mpfr_ptr (pointeur vers
une certaine structure), la liste devant se terminer par un pointeur
nul. Je suppose que c'est incorrect et qu'on aurait dû écrire

mpfr_clears (s, u, v, w, (mpfr_ptr) 0);

car (mpfr_ptr) 0 et (void *) 0 n'ont pas forcément la même
représentation, puisque les divers types pointeurs n'ont même pas
forcément la même taille. Ai-je bien compris et dois-je corriger
le code (au cas où...)?

--
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 <founia$gtv$,
Antoine Leca écrit:

Donc plus de conversions ! Raison (pas la seule) pour laquelle 'candide' a
eu bien raison, au début de l'enfilade, d'écrire

printf("%pn%pn", (void *) a, (void *) &a);


Hmm... Je m'aperçois que dans MPFR, on a du code du genre:

mpfr_clears (s, u, v, w, (void *) 0);

où la fonction attend des arguments du type mpfr_ptr (pointeur vers
une certaine structure), la liste devant se terminer par un pointeur
nul. Je suppose que c'est incorrect et qu'on aurait dû écrire

mpfr_clears (s, u, v, w, (mpfr_ptr) 0);

car (mpfr_ptr) 0 et (void *) 0 n'ont pas forcément la même
représentation, puisque les divers types pointeurs n'ont même pas
forcément la même taille. Ai-je bien compris et dois-je corriger
le code (au cas où...)?


C'est ma comprehension. Le "cas ou" me semble assez improbable. La mode
n'est plus aux machines adressables par mot. A ma connaissance, les
implementations de C recentes pour celles-ci preferent prendre une taille
de char plus grande plutot que de batir des "pointeur gras" pour les char
parce qu'elles n'ont pas vocation a manipuler des char.

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
Antoine Leca
En news:20080213144550$, Vincent Lefevre va
escriure:
Ai-je bien compris


Oui

et dois-je corriger le code (au cas où...)?


Euh, cela c'est autre chose... parce qu'il va te falloir expliquer cela à
ceusses qui doivent valider la modif', sachant bien sûr que dans 99,99% des
cas d'emploi c'est complètement stérile.
Et par ailleurs, il va te falloir rajouter un commentaire explicatif, pour
éviter qu'un musardeur (les correcteurs de points-virgules, comme ils les
appelent sur NetBSD) ne trouvent ton code zarbi, et ne remettent le
canonique (void*) à la place !


Sinon, comme c'est un pointeur vers structure, la représentation est
conjointe pour les pointeurs vers n'importe quel type structure (y compris
une structure anonyme ne contenant qu'un char). Donc, bien que le
comportement soit normativement indéfini, il ne peut y avoir un effet
perceptible que dans le cas où la représentation telle que passée sur la
pile des pointeurs vers type caractère est différente de celle générique des
pointeurs vers structures, ou bien si on utilise une implémentation qui
vérifie effectivement à l'exécution la compatibilité réelle des types... En
dehors de la DS9k, je pense que cela ne doit pas être très courant.


Antoine

Avatar
Jean-Marc Bourguet
"Antoine Leca" writes:

Sinon, comme c'est un pointeur vers structure, la représentation est
conjointe pour les pointeurs vers n'importe quel type structure (y
compris une structure anonyme ne contenant qu'un char).


C'est vrai aussi sur ta DS9K? (Je pense au cas tres tordu de
representations de pointeurs differentes suivant le tag, mais je ne me suis
pas amuse a faire l'exesege pour voir si c'est conforme ou pas.).

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
Antoine Leca
En news:,
Jean-Marc Bourguet va escriure:
"Antoine Leca" writes:

Sinon, comme c'est un pointeur vers structure, la représentation est
conjointe pour les pointeurs vers n'importe quel type structure (y
compris une structure anonyme ne contenant qu'un char).


C'est vrai aussi sur ta DS9K? (Je pense au cas tres tordu de
representations de pointeurs differentes suivant le tag, mais je ne
me suis pas amuse a faire l'exesege pour voir si c'est conforme ou
pas.).


C'est totalement ésotérique (comme tout ce qui touche les DS9k :o) ), mais
il faut respecter

6.2.5 Types

[#27] A pointer to void shall have the same representation and
alignment requirements as a pointer to a character type*.
Similarly, pointers to qualified or unqualified versions of
compatible types shall have the same representation and
alignment requirements. All pointers to structure types
shall have the same representation and alignment requirements
as each other. All pointers to union types shall have the
same representation and alignment requirements as each other.
Pointers to other types need not have the same representation
or alignment requirements.
__________
Note (not normative) :
*: The same representation and alignment requirements are meant to
imply interchangeability as arguments to functions, return
values from functions, and members of unions.


Maintenant, on peut toujours coller dans le pointeur (qui serait en fait un
handle) l'information de type, donc avoir la possibilité de faire sauter le
bouchon (comportement indéfini) au moment de l'utilisation, dans les cas où
les pointeurs ne sont pas vers des types compatibles.


En fait, je m'aperçois que je ne retrouve plus la bonne raison pour la
contrainte formulée sur les types pointeurs vers structure ou vers union ;
je « sais » cependant que cela a quelque chose à voir avec les types ADT,
polymorphisme etc. Ce texte semble absent de C89 (à première vue, sur la
copie électronique ; il faudrait que je relise la version papier pour en
être sûr.) De plus, la lecture du
http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_314.htm et de ses
attenants (N1226, N1237) me fait penser que cela doit être lié (et encore un
vilain jeu de mots :o)...)


Antoine


Avatar
Vincent Lefevre
Dans l'article <fov1hc$l77$,
Antoine Leca écrit:

En news:20080213144550$, Vincent Lefevre va
escriure:

et dois-je corriger le code (au cas où...)?


Euh, cela c'est autre chose... parce qu'il va te falloir expliquer
cela à ceusses qui doivent valider la modif', sachant bien sûr que
dans 99,99% des cas d'emploi c'est complètement stérile.


Étant donné qu'on n'est en ce moment que 3 développeurs actifs, c'est
probablement le moment de le faire, surtout que rien ne dit qu'il ne
se posera pas dans quelques années parce que le compilateur aura une
option qui permettra de faire telle ou telle vérification.

Et par ailleurs, il va te falloir rajouter un commentaire
explicatif, pour éviter qu'un musardeur (les correcteurs de
points-virgules, comme ils les appelent sur NetBSD) ne trouvent ton
code zarbi, et ne remettent le canonique (void*) à la place !


On met ce genre de choses dans le fichier "README.dev". Il y a déjà pas
mal de règles encore plus bizarres pour éviter les bugs de compilateurs
auxquels on a été confrontés.

--
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
Marc Boyer
On 2008-02-12, Antoine Leca wrote:
Comme un sujet analogue court sur comp.std.c (à partir d'une remarque dans
news:97aa3$47afd2a8$ca8010a3$, Larry Jones a lancé
news: sur le même sujet de &array), j'ai
glissé une référence vers notre discussion et nos questions, peut-être que
les gourous et autres sorciers vont donner des réponses plus précises à nos
interrogations.


Et la réponse est

"It could require that the pointers, suitably converted, compare equal,
like it does for a struct and its first member. I'm certain that that
was the intent and the only reason it wasn't spelled out was that it was
too obvious for anyone to have thought of."

C'est la réponse pragmatique...

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

2 3 4 5 6