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].
Dans l'article <slrnfr34i6.mei.Marc.Boyer@ubu.enseeiht.fr>,
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> écrit:
On 2008-02-12, Antoine Leca <root@localhost.invalid> 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].
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].
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] );
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.
Après, pour une vérification dynamique, je serais tenté de mettre
des choses après ou avant le tableau, mais en regardant 6.5.9p6 et la
note de bas de page 91, je me demande si on a le droit.
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] );
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.
Après, pour une vérification dynamique, je serais tenté de mettre
des choses après ou avant le tableau, mais en regardant 6.5.9p6 et la
note de bas de page 91, je me demande si on a le droit.
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] );
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.
Après, pour une vérification dynamique, je serais tenté de mettre
des choses après ou avant le tableau, mais en regardant 6.5.9p6 et la
note de bas de page 91, je me demande si on a le droit.
"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);
"Antoine Leca" <root@localhost.invalid> writes:
En news:slrnfr0o13.r2n.Marc.Boyer@ubu.enseeiht.fr, 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);
"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);
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?
Dans l'article <slrnfr35rq.mei.Marc.Boyer@ubu.enseeiht.fr>,
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> écrit:
On 2008-02-12, Antoine Leca <root@localhost.invalid> 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?
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?
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' ?
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' ?
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' ?
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])
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])
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])
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] );
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.
Huh ?
Si tu n'as pas inclus de prototypes pour memcpy(), le comportement de ton
code n'est pas défini (6.5.2.2p6, dernière phrase, tu passes un pointeur
vers tableau qui n'est pas à ma connaissance compatible avec un void*).
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...
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] );
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.
Huh ?
Si tu n'as pas inclus de prototypes pour memcpy(), le comportement de ton
code n'est pas défini (6.5.2.2p6, dernière phrase, tu passes un pointeur
vers tableau qui n'est pas à ma connaissance compatible avec un void*).
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...
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] );
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.
Huh ?
Si tu n'as pas inclus de prototypes pour memcpy(), le comportement de ton
code n'est pas défini (6.5.2.2p6, dernière phrase, tu passes un pointeur
vers tableau qui n'est pas à ma connaissance compatible avec un void*).
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...
Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
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. 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:
[#7] EXAMPLE 3 In this example, the size of a variable-
length array is computed and returned from a function:
size_t fsize3 (int n)
{
char b[n+3]; // Variable length array.
return sizeof b; // Execution time sizeof.
}
int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13.
return 0;
}
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. 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:
[#7] EXAMPLE 3 In this example, the size of a variable-
length array is computed and returned from a function:
size_t fsize3 (int n)
{
char b[n+3]; // Variable length array.
return sizeof b; // Execution time sizeof.
}
int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13.
return 0;
}
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. 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:
[#7] EXAMPLE 3 In this example, the size of a variable-
length array is computed and returned from a function:
size_t fsize3 (int n)
{
char b[n+3]; // Variable length array.
return sizeof b; // Execution time sizeof.
}
int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13.
return 0;
}
Dans l'article ,
Marc Boyer écrit:Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
Les tableaux ne semblent pas pouvoir avoir de padding:
6.5.3.4 The sizeof operator
[...]
[#3] When applied to an operand that has type char, unsigned
char, or signed char, (or a qualified version thereof) the
result is 1. When applied to an operand that has array
type, the result is the total number of bytes in the
array.75) When applied to an operand that has structure or
union type, the result is the total number of bytes in such
an object, including internal and trailing padding.
Tu remarqueras que la norme parle de padding pour les structures,
mais est silencieuse pour les tableaux.
Un peu plus loin:
[#6] EXAMPLE 2 Another use of the sizeof operator is to
compute the number of elements in an array:
sizeof array / sizeof array[0]
Cet exemple deviendrait faux s'il y avait du padding.
Et j'ai aussi
cité l'exemple 3 dans un article précédent.
Dans l'article <slrnfr3ddf.mei.Marc.Boyer@ubu.enseeiht.fr>,
Marc Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> écrit:
Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
Les tableaux ne semblent pas pouvoir avoir de padding:
6.5.3.4 The sizeof operator
[...]
[#3] When applied to an operand that has type char, unsigned
char, or signed char, (or a qualified version thereof) the
result is 1. When applied to an operand that has array
type, the result is the total number of bytes in the
array.75) When applied to an operand that has structure or
union type, the result is the total number of bytes in such
an object, including internal and trailing padding.
Tu remarqueras que la norme parle de padding pour les structures,
mais est silencieuse pour les tableaux.
Un peu plus loin:
[#6] EXAMPLE 2 Another use of the sizeof operator is to
compute the number of elements in an array:
sizeof array / sizeof array[0]
Cet exemple deviendrait faux s'il y avait du padding.
Et j'ai aussi
cité l'exemple 3 dans un article précédent.
Dans l'article ,
Marc Boyer écrit:Non, non, 6.5.9p6 dit "at its beginning"... Oui, je pinaille.
En gros, est-ce qu'on pourrait avoir du padding au début d'un tableau ?
Je pense que oui, ssi il est d'une taille < à la taille d'un élément.
Les tableaux ne semblent pas pouvoir avoir de padding:
6.5.3.4 The sizeof operator
[...]
[#3] When applied to an operand that has type char, unsigned
char, or signed char, (or a qualified version thereof) the
result is 1. When applied to an operand that has array
type, the result is the total number of bytes in the
array.75) When applied to an operand that has structure or
union type, the result is the total number of bytes in such
an object, including internal and trailing padding.
Tu remarqueras que la norme parle de padding pour les structures,
mais est silencieuse pour les tableaux.
Un peu plus loin:
[#6] EXAMPLE 2 Another use of the sizeof operator is to
compute the number of elements in an array:
sizeof array / sizeof array[0]
Cet exemple deviendrait faux s'il y avait du padding.
Et j'ai aussi
cité l'exemple 3 dans un article précédent.