est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
soit le bout de code suivant :
------------------------------------------------------------------------
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
------------------------------------------------------------------------
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
soit le bout de code suivant :
------------------------------------------------------------------------
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
------------------------------------------------------------------------
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
soit le bout de code suivant :
------------------------------------------------------------------------
typedef struct foo foo;
struct my_union {
union {
foo *array[2];
struct {
foo *first;
foo *second;
}
}
} my_union;
------------------------------------------------------------------------
soit 'bar' du type my_union, en supposant que tous les membres sont alloués.
est ce que je suis toujours sur que :
&bar->array[0] == &bar->first
&bar->array[1] == &bar->second
&bar->array[0] == &bar->first
Oui, mais par contre&bar->array[1] == &bar->second
ceci n'est pas garanti par la norme.
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
&bar->array[0] == &bar->first
Oui, mais par contre
&bar->array[1] == &bar->second
ceci n'est pas garanti par la norme.
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
&bar->array[0] == &bar->first
Oui, mais par contre&bar->array[1] == &bar->second
ceci n'est pas garanti par la norme.
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de mon
union, du pointeur auquel il font référence. ca m'aurait permis de faire
des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de mon
union, du pointeur auquel il font référence. ca m'aurait permis de faire
des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de mon
union, du pointeur auquel il font référence. ca m'aurait permis de faire
des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
On Sat, 17 Sep 2005 21:04:24 +0200, Pierre Habouzit wrote:
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de
mon union, du pointeur auquel il font référence. ca m'aurait permis de
faire des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
Excusez-moi, mais j'ai du mal à comprendre votre problème; ce n'est pas
à la portée d'un débutant, est-ce que vous pourriez le préciser pour
que tout le monde suive ?
On Sat, 17 Sep 2005 21:04:24 +0200, Pierre Habouzit wrote:
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de
mon union, du pointeur auquel il font référence. ca m'aurait permis de
faire des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
Excusez-moi, mais j'ai du mal à comprendre votre problème; ce n'est pas
à la portée d'un débutant, est-ce que vous pourriez le préciser pour
que tout le monde suive ?
On Sat, 17 Sep 2005 21:04:24 +0200, Pierre Habouzit wrote:
hmmm, c'est bien dommage.
J'ai des structures dont un des membres est l'indice dans le tableau de
mon union, du pointeur auquel il font référence. ca m'aurait permis de
faire des trucs du genre :
bar->array[baz->some_index]
Mais lorsque j'y accède textuellement je voulais éviter des
bar->array[MY_UNION_FIRST] ... et donc pouvoir accéder aux pointeurs du
tableau par leur "nom".
Excusez-moi, mais j'ai du mal à comprendre votre problème; ce n'est pas
à la portée d'un débutant, est-ce que vous pourriez le préciser pour
que tout le monde suive ?
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
D'une façon générale, ce n'est pas une bonne idée d'écrire dans un
membre d'une union est de lire dans un autre. Une union, c'est pas fait
pour ça.
Parce que si il s'agit juste de pouvoir "embarquer" plusieurs types
différents, autant utiliser une zone mémoire pointée depuis un void* ... ca
offre à peu près les même propriétés.
Le void* n'est pas déterministe. Il est totalement souple par nature et
Sinon *juste pour ma culture personnelle* -- je ne compte certainement pas
l'utiliser si la norme l'interdit ou ne le spécifie pas -- y a-t-il
vraiment *beaucoup* de compilateurs/architectures où une struct avec deux
pointeurs sur le même type, ne sont pas alignés pareil que un tableau avec
deux de ces pointeurs ?
donc reposons la question autrement. si my_type est un type qui représente
la plus grosse valeur entière manipulable par le système (c'est pas
rigoureux comme définition, mais vous comprendrez sans doute mon point).
est-ce stupide de supposer que :
Parce que si il s'agit juste de pouvoir "embarquer" plusieurs types
différents, autant utiliser une zone mémoire pointée depuis un void* ... ca
offre à peu près les même propriétés.
Le void* n'est pas déterministe. Il est totalement souple par nature et
Sinon *juste pour ma culture personnelle* -- je ne compte certainement pas
l'utiliser si la norme l'interdit ou ne le spécifie pas -- y a-t-il
vraiment *beaucoup* de compilateurs/architectures où une struct avec deux
pointeurs sur le même type, ne sont pas alignés pareil que un tableau avec
deux de ces pointeurs ?
donc reposons la question autrement. si my_type est un type qui représente
la plus grosse valeur entière manipulable par le système (c'est pas
rigoureux comme définition, mais vous comprendrez sans doute mon point).
est-ce stupide de supposer que :
Parce que si il s'agit juste de pouvoir "embarquer" plusieurs types
différents, autant utiliser une zone mémoire pointée depuis un void* ... ca
offre à peu près les même propriétés.
Le void* n'est pas déterministe. Il est totalement souple par nature et
Sinon *juste pour ma culture personnelle* -- je ne compte certainement pas
l'utiliser si la norme l'interdit ou ne le spécifie pas -- y a-t-il
vraiment *beaucoup* de compilateurs/architectures où une struct avec deux
pointeurs sur le même type, ne sont pas alignés pareil que un tableau avec
deux de ces pointeurs ?
donc reposons la question autrement. si my_type est un type qui représente
la plus grosse valeur entière manipulable par le système (c'est pas
rigoureux comme définition, mais vous comprendrez sans doute mon point).
est-ce stupide de supposer que :
mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
struct {
const blob_t *original;
blob_t *scratch;
};
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
struct {
const blob_t *original;
blob_t *scratch;
};
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
struct {
const blob_t *original;
blob_t *scratch;
};
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
Pierre Habouzit wrote:
Merci pour l'explication, je crois avoir compris jusqu'ici.mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
Je ne comprends plus à partir d'ici.struct {
const blob_t *original;
blob_t *scratch;
};
Pourquoi garder la structure au dessus, et -peut-être suis-je mal
réveillé- comment y accéder sans la nommer ?
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
Ou 8 suivant la taille du pointeur.
Mais je n'en vois pas l'interêt.
Pourquoi cela au-dessous ne suffirait-il pas ? :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
De plus, je ne vois pas l'intérêt d'éloigner le bit modified du tableau
de pointeurs en le mettant dans un (ou des) header, puisque le fait que
le buffer soit modifié semble dépendre du message et non de ces
headers.
Mais je n'ai peut-être pas tout compris.
sur ce point en effet. mon message est un message ressemblant à un mail (en
Pierre Habouzit wrote:
Merci pour l'explication, je crois avoir compris jusqu'ici.
mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
Je ne comprends plus à partir d'ici.
struct {
const blob_t *original;
blob_t *scratch;
};
Pourquoi garder la structure au dessus, et -peut-être suis-je mal
réveillé- comment y accéder sans la nommer ?
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
Ou 8 suivant la taille du pointeur.
Mais je n'en vois pas l'interêt.
Pourquoi cela au-dessous ne suffirait-il pas ? :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
De plus, je ne vois pas l'intérêt d'éloigner le bit modified du tableau
de pointeurs en le mettant dans un (ou des) header, puisque le fait que
le buffer soit modifié semble dépendre du message et non de ces
headers.
Mais je n'ai peut-être pas tout compris.
sur ce point en effet. mon message est un message ressemblant à un mail (en
Pierre Habouzit wrote:
Merci pour l'explication, je crois avoir compris jusqu'ici.mais du coup, vu que je ne peux garantir que scratch coincide avec la
deuxième case du tablea __bufs, je me suis résigné à avoir comme type
pour mes messages :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
Je ne comprends plus à partir d'ici.struct {
const blob_t *original;
blob_t *scratch;
};
Pourquoi garder la structure au dessus, et -peut-être suis-je mal
réveillé- comment y accéder sans la nommer ?
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
ce qui me force à maintenir l'invariant __bufs[0] == original et
__bufs[1]==scratch à la main, mais vu que ces pointeurs changent peu,
c'est pas trop génant pour moi, et autant je ne voulais pas perdre la
taille d'un pointeur en plus dans mes headers vu que j'en ai beaucoup
et que j'avais déjà des champs de bits, mais perdre 16 octets dans la
structure de message n'est pas trop génant. (enfin 16 ou plutot
sizof(blob_t*)*2)
Ou 8 suivant la taille du pointeur.
Mais je n'en vois pas l'interêt.
Pourquoi cela au-dessous ne suffirait-il pas ? :
struct message {
[ ... pleins de choses dont pas mal de 'headers' ...];
blob_t *__bufs[2];
[ ... encore pleins de choses ...];
};
De plus, je ne vois pas l'intérêt d'éloigner le bit modified du tableau
de pointeurs en le mettant dans un (ou des) header, puisque le fait que
le buffer soit modifié semble dépendre du message et non de ces
headers.
Mais je n'ai peut-être pas tout compris.
sur ce point en effet. mon message est un message ressemblant à un mail (en