En news:, Marc Boyer va escriure: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*.
Tu as sauté un épisode ! C'est justement pour éviter ces conversions
intermédiaires que j'ai changé les int initiaux en char, et remplacer a par
b ! ;-)
on a
p == &b
Mais est-ce que 'p' pointe 'at its beginning' ?
Je crois (après avoir lu ton autre message) que c'est préférable si l'on
veut que memcpy() fonctionne...
Maintenant, je ne sais pas démontrer que c'est garanti par la norme. Il y a
un flou entre 6.2.5p27 (même représentation pour void* et char*), 6.3.2.3p1
(conversion vers et depuis void*) et 6.5.6p8 (égalité de pointeurs) qui ne
me permettent pas d'éclaircir toutes les alternatives.
En d'autres termes, je ne suis pas sûr que ton exemple
#include <string.h>
#include <assert.h>
int main()
{
static const int a[5]= { 10 , -9 , 8 , -7 , 6 };
int b[20];
memcpy(&b, &a, sizeof a );
assert( a[0] == b[0] );
return 0;
}
soit strictement conforme _et_ muet.
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.
En news:slrnfr35rq.mei.Marc.Boyer@ubu.enseeiht.fr, Marc Boyer va escriure:
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*.
Tu as sauté un épisode ! C'est justement pour éviter ces conversions
intermédiaires que j'ai changé les int initiaux en char, et remplacer a par
b ! ;-)
on a
p == &b
Mais est-ce que 'p' pointe 'at its beginning' ?
Je crois (après avoir lu ton autre message) que c'est préférable si l'on
veut que memcpy() fonctionne...
Maintenant, je ne sais pas démontrer que c'est garanti par la norme. Il y a
un flou entre 6.2.5p27 (même représentation pour void* et char*), 6.3.2.3p1
(conversion vers et depuis void*) et 6.5.6p8 (égalité de pointeurs) qui ne
me permettent pas d'éclaircir toutes les alternatives.
En d'autres termes, je ne suis pas sûr que ton exemple
#include <string.h>
#include <assert.h>
int main()
{
static const int a[5]= { 10 , -9 , 8 , -7 , 6 };
int b[20];
memcpy(&b, &a, sizeof a );
assert( a[0] == b[0] );
return 0;
}
soit strictement conforme _et_ muet.
Comme un sujet analogue court sur comp.std.c (à partir d'une remarque dans
news:97aa3$47afd2a8$ca8010a3$28952@saipan.com, Larry Jones a lancé
news:0ae685-5l7.ln1@jones.homeip.net 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.
En news:, Marc Boyer va escriure: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*.
Tu as sauté un épisode ! C'est justement pour éviter ces conversions
intermédiaires que j'ai changé les int initiaux en char, et remplacer a par
b ! ;-)
on a
p == &b
Mais est-ce que 'p' pointe 'at its beginning' ?
Je crois (après avoir lu ton autre message) que c'est préférable si l'on
veut que memcpy() fonctionne...
Maintenant, je ne sais pas démontrer que c'est garanti par la norme. Il y a
un flou entre 6.2.5p27 (même représentation pour void* et char*), 6.3.2.3p1
(conversion vers et depuis void*) et 6.5.6p8 (égalité de pointeurs) qui ne
me permettent pas d'éclaircir toutes les alternatives.
En d'autres termes, je ne suis pas sûr que ton exemple
#include <string.h>
#include <assert.h>
int main()
{
static const int a[5]= { 10 , -9 , 8 , -7 , 6 };
int b[20];
memcpy(&b, &a, sizeof a );
assert( a[0] == b[0] );
return 0;
}
soit strictement conforme _et_ muet.
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.
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
On 2008-02-12, Antoine Leca wrote:memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
Je suppose que, formellement, il faut faire le cast en void* avant
un appel à memcpy, c'est ça ?
C'est vrai que je ne le fais jamais... Honte à moi...
On 2008-02-12, Antoine Leca wrote:
memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
Je suppose que, formellement, il faut faire le cast en void* avant
un appel à memcpy, c'est ça ?
C'est vrai que je ne le fais jamais... Honte à moi...
On 2008-02-12, Antoine Leca wrote:memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
Je suppose que, formellement, il faut faire le cast en void* avant
un appel à memcpy, c'est ça ?
C'est vrai que je ne le fais jamais... Honte à moi...
En news:, Marc Boyer va escriure:On 2008-02-12, Antoine Leca wrote:memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
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).
C'est vrai que je ne le fais jamais... Honte à moi...
Si tu écris du code sans prototype (ce qui m'étonnerait), effectivement
honte à toi. ;-)
La question de savoir si c'est dommage ou pas que ce ne soit plus un
problème dans la pratique est... bof non, ce n'est pas une bonne question !
En news:slrnfr3gjt.mei.Marc.Boyer@ubu.enseeiht.fr, Marc Boyer va escriure:
On 2008-02-12, Antoine Leca wrote:
memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
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).
C'est vrai que je ne le fais jamais... Honte à moi...
Si tu écris du code sans prototype (ce qui m'étonnerait), effectivement
honte à toi. ;-)
La question de savoir si c'est dommage ou pas que ce ne soit plus un
problème dans la pratique est... bof non, ce n'est pas une bonne question !
En news:, Marc Boyer va escriure:On 2008-02-12, Antoine Leca wrote:memcpy(&b, &a, sizeof a );
OK. Disons que le <string.h> était implicite dans mon post.
Si tu as explicité le prototype, ou si tu as #inclut <string.h>, tu
as écris en fait
memcpy((void*)&b, (void*)&a, sizeof a );
et circulez, il n'y a plus de descripteur à voir...
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).
C'est vrai que je ne le fais jamais... Honte à moi...
Si tu écris du code sans prototype (ce qui m'étonnerait), effectivement
honte à toi. ;-)
La question de savoir si c'est dommage ou pas que ce ne soit plus un
problème dans la pratique est... bof non, ce n'est pas une bonne question !
Vincent Lefevre <vincent+ écrivait :AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
D'un autre côté quand je fais un malloc(sizeof(type)*numElements) il y a
très souvent des données avant le pointeur retourné. Ne serait-ce que
des données utilisées par l'allocateur, pour pouvoir effectuer free().
Vincent Lefevre <vincent+news@vinc17.org> écrivait :
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
D'un autre côté quand je fais un malloc(sizeof(type)*numElements) il y a
très souvent des données avant le pointeur retourné. Ne serait-ce que
des données utilisées par l'allocateur, pour pouvoir effectuer free().
Vincent Lefevre <vincent+ écrivait :AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur. Je ne sais pas
si la norme le dit explicitement. Mais si on suppose que l'égalité
n'est pas forcément respectée parce que l'objet tableau peut contenir
des données avant son premier élément, alors plein de choses deviennent
incorrectes dans la norme. Par exemple:
D'un autre côté quand je fais un malloc(sizeof(type)*numElements) il y a
très souvent des données avant le pointeur retourné. Ne serait-ce que
des données utilisées par l'allocateur, pour pouvoir effectuer free().
Dans l'article ,
Marc Boyer écrit:Dans mon idée, justement non.
On part sur la question: est-ce que
(void*) a == (void*) &a
et on essaye de voir si la norme laisse (intentionnellement ou non)
la place pour une implantation conforme dans laquelle
(void*) a != (void*) &a
sachant qu'on a déjà bien sûr
(void*) a == (void*) (&a[0])
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Dans l'article <slrnfr3bv3.mei.Marc.Boyer@ubu.enseeiht.fr>,
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> écrit:
Dans mon idée, justement non.
On part sur la question: est-ce que
(void*) a == (void*) &a
et on essaye de voir si la norme laisse (intentionnellement ou non)
la place pour une implantation conforme dans laquelle
(void*) a != (void*) &a
sachant qu'on a déjà bien sûr
(void*) a == (void*) (&a[0])
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Dans l'article ,
Marc Boyer écrit:Dans mon idée, justement non.
On part sur la question: est-ce que
(void*) a == (void*) &a
et on essaye de voir si la norme laisse (intentionnellement ou non)
la place pour une implantation conforme dans laquelle
(void*) a != (void*) &a
sachant qu'on a déjà bien sûr
(void*) a == (void*) (&a[0])
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
In article <20080212152318$,
Vincent Lefevre <vincent+ wrote:AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
In article <20080212152318$4985@prunille.vinc17.org>,
Vincent Lefevre <vincent+news@vinc17.org> wrote:
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
In article <20080212152318$,
Vincent Lefevre <vincent+ wrote:AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
Dans l'article <fosth4$16iu$,
Marc Espie écrit:In article <20080212152318$,
Vincent Lefevre <vincent+ wrote:AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
Dans l'article <fosth4$16iu$1@biggoron.nerim.net>,
Marc Espie <espie@lain.home> écrit:
In article <20080212152318$4985@prunille.vinc17.org>,
Vincent Lefevre <vincent+news@vinc17.org> wrote:
AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
Dans l'article <fosth4$16iu$,
Marc Espie écrit:In article <20080212152318$,
Vincent Lefevre <vincent+ wrote:AMHA, on a forcément (void*) a == (void*) &a, i.e. l'objet tableau
doit débuter sur son premier élément a[0], enfin tout du moins
c'est ce qui doit être visible pour l'utilisateur.
Non, la norme n'est pas d'accord. La norme ne te dit pas ce que doit
donner &a, ou plus exacement comme prendre l'adresse d'un tableau.
Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
In article <20080212232405$,
Vincent Lefevre <vincent+ wrote:Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
Je ne suis pas d'accord, ca n'est pas ce qui est ecrit dans la norme.
6.5.3.2#3 te dit effectivement que &a retourne l'adresse de a, et plus
precisemment un pointeur vers l'objet a.
Et 6.3.2.3#7 te dit que le pointeur vers a peut etre converti en pointeur
vers un type different, et reconverti vers le pointeur de depart.
In article <20080212232405$1cdd@prunille.vinc17.org>,
Vincent Lefevre <vincent+news@vinc17.org> wrote:
Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
Je ne suis pas d'accord, ca n'est pas ce qui est ecrit dans la norme.
6.5.3.2#3 te dit effectivement que &a retourne l'adresse de a, et plus
precisemment un pointeur vers l'objet a.
Et 6.3.2.3#7 te dit que le pointeur vers a peut etre converti en pointeur
vers un type different, et reconverti vers le pointeur de depart.
In article <20080212232405$,
Vincent Lefevre <vincent+ wrote:Si. Le tableau est un objet et &a pointe sur cet objet (6.5.3.2#3),
i.e. le premier multiplet de cet objet (6.3.2.3#7). Ensuite le
Je ne suis pas d'accord, ca n'est pas ce qui est ecrit dans la norme.
6.5.3.2#3 te dit effectivement que &a retourne l'adresse de a, et plus
precisemment un pointeur vers l'objet a.
Et 6.3.2.3#7 te dit que le pointeur vers a peut etre converti en pointeur
vers un type different, et reconverti vers le pointeur de depart.
Je rappelle ce qu'on cherchait à montrer:
(void*) a == (void*) &a
Comme l'égalité ci-dessus est équivalente à
&a[0] == &a
Je rappelle ce qu'on cherchait à montrer:
(void*) a == (void*) &a
Comme l'égalité ci-dessus est équivalente à
&a[0] == &a
Je rappelle ce qu'on cherchait à montrer:
(void*) a == (void*) &a
Comme l'égalité ci-dessus est équivalente à
&a[0] == &a