Decalages d'un nombre de bits pouvant etre >= a la taille du type
134 réponses
Vincent Lefevre
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
Dans l'article <cjvbua$f0p$, Charlie Gordon écrit:
Après relecture du standard, il apparait que 1>>32 c'est undefined behavior, y compris pendant la translation. Je pense quand même que 1 ? 0 : 1>>32 est sémantiquement correct, d'ailleurs 6.6 paragraphe 3 prévoit le cas d'expressions constantes dont des sous-expressions non constantes ne sont jamais évaluées. Par exemple :
L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi l'évaluer en tant que sous-expression constante (sans chercher à savoir si la valeur pourra être utilisée ou si elle ne sera jamais utilisée), et dans ce cas, il y a comportement indéfini.
Non. Le comportement de
1 ? 0 : 1>>32
est défini de par la norme. Le fait qu'une expression constante pourrait être évaluée "physiquement" pendant la traduction ne touche pas le fait qu'elle n'est évaluée dans la machine abstraite si et seulement si la norme dit qu'elle sera évaluée.
D'ailleurs la norme donne comme exemple d'une expression définie:
static int i = 2 || 1/0;
-- Horst
-- Lâche pas la patate!
Vincent Lefevre <vincent+news@vinc17.org> wrote:
Dans l'article <cjvbua$f0p$1@news.tiscali.fr>,
Charlie Gordon <news@chqrlie.org> écrit:
Après relecture du standard, il apparait que 1>>32 c'est undefined behavior,
y compris pendant la translation.
Je pense quand même que 1 ? 0 : 1>>32 est sémantiquement correct,
d'ailleurs 6.6 paragraphe 3 prévoit le cas d'expressions constantes dont des
sous-expressions non constantes ne sont jamais évaluées. Par exemple :
L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi
l'évaluer en tant que sous-expression constante (sans chercher à
savoir si la valeur pourra être utilisée ou si elle ne sera jamais
utilisée), et dans ce cas, il y a comportement indéfini.
Non. Le comportement de
1 ? 0 : 1>>32
est défini de par la norme. Le fait qu'une expression constante
pourrait être évaluée "physiquement" pendant la traduction ne touche
pas le fait qu'elle n'est évaluée dans la machine abstraite si et
seulement si la norme dit qu'elle sera évaluée.
D'ailleurs la norme donne comme exemple d'une expression définie:
Dans l'article <cjvbua$f0p$, Charlie Gordon écrit:
Après relecture du standard, il apparait que 1>>32 c'est undefined behavior, y compris pendant la translation. Je pense quand même que 1 ? 0 : 1>>32 est sémantiquement correct, d'ailleurs 6.6 paragraphe 3 prévoit le cas d'expressions constantes dont des sous-expressions non constantes ne sont jamais évaluées. Par exemple :
L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi l'évaluer en tant que sous-expression constante (sans chercher à savoir si la valeur pourra être utilisée ou si elle ne sera jamais utilisée), et dans ce cas, il y a comportement indéfini.
Non. Le comportement de
1 ? 0 : 1>>32
est défini de par la norme. Le fait qu'une expression constante pourrait être évaluée "physiquement" pendant la traduction ne touche pas le fait qu'elle n'est évaluée dans la machine abstraite si et seulement si la norme dit qu'elle sera évaluée.
D'ailleurs la norme donne comme exemple d'une expression définie:
static int i = 2 || 1/0;
-- Horst
-- Lâche pas la patate!
Gabriel Dos Reis
Laurent Deniau writes:
| Vincent Lefevre wrote: | > Dans l'article <ck3g2f$1im$, | > Laurent Deniau écrit: | > | >> Le cast n'est pas un probleme selon tes propos (c'etait ma premiere | >> question) et il est biensur essentiel pour fixer le type de index_t. | > Le cast en lui-même n'était pas un problème dans ton exemple | > (qui n'utilisait pas le préprocesseur), mais qui ne résolvait | > pas non plus le problème. | > | >>Le choix du unsigned long n'est pas anodin. Il correspond | >>generalement au plus gros mot processeur (32, 64, 128, ...) | > Non, c'est complètement faux! Sur une machine 32 bits, un | > unsigned long fait 32 bits, alors qu'un unsigned long long | > en fait 64. | | Je parle chinois? relis ce que j'ai ecrit stp...
bah, tu parles pas Éwé en tout cas :-)
-- Gaby
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
| Vincent Lefevre wrote:
| > Dans l'article <ck3g2f$1im$1@sunnews.cern.ch>,
| > Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
| >
| >> Le cast n'est pas un probleme selon tes propos (c'etait ma premiere
| >> question) et il est biensur essentiel pour fixer le type de index_t.
| > Le cast en lui-même n'était pas un problème dans ton exemple
| > (qui n'utilisait pas le préprocesseur), mais qui ne résolvait
| > pas non plus le problème.
| >
| >>Le choix du unsigned long n'est pas anodin. Il correspond
| >>generalement au plus gros mot processeur (32, 64, 128, ...)
| > Non, c'est complètement faux! Sur une machine 32 bits, un
| > unsigned long fait 32 bits, alors qu'un unsigned long long
| > en fait 64.
|
| Je parle chinois? relis ce que j'ai ecrit stp...
| Vincent Lefevre wrote: | > Dans l'article <ck3g2f$1im$, | > Laurent Deniau écrit: | > | >> Le cast n'est pas un probleme selon tes propos (c'etait ma premiere | >> question) et il est biensur essentiel pour fixer le type de index_t. | > Le cast en lui-même n'était pas un problème dans ton exemple | > (qui n'utilisait pas le préprocesseur), mais qui ne résolvait | > pas non plus le problème. | > | >>Le choix du unsigned long n'est pas anodin. Il correspond | >>generalement au plus gros mot processeur (32, 64, 128, ...) | > Non, c'est complètement faux! Sur une machine 32 bits, un | > unsigned long fait 32 bits, alors qu'un unsigned long long | > en fait 64. | | Je parle chinois? relis ce que j'ai ecrit stp...
bah, tu parles pas Éwé en tout cas :-)
-- Gaby
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:
| Dans l'article , | Gabriel Dos Reis écrit: | | > Vincent Lefevre <vincent+ writes: | | > | Dans l'article <cjvbua$f0p$, | > | Charlie Gordon écrit: | | > | > 1 ? 0 : 1>>32 | > | | > | L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi | > | l'évaluer en tant que sous-expression constante (sans chercher à | > | savoir si la valeur pourra être utilisée ou si elle ne sera jamais | > | utilisée), et dans ce cas, il y a comportement indéfini. | | > Bah non ; ce n'est pas un comportement possible de la machine | > abstraite. | | Sur quoi tu te bases?
Le machin que tu cites à tout le monde.
-- Gaby
Vincent Lefevre <vincent+news@vinc17.org> writes:
| Dans l'article <m34ql8lgx0.fsf@merlin.cs.tamu.edu>,
| Gabriel Dos Reis <gdr@cs.tamu.edu> écrit:
|
| > Vincent Lefevre <vincent+news@vinc17.org> writes:
|
| > | Dans l'article <cjvbua$f0p$1@news.tiscali.fr>,
| > | Charlie Gordon <news@chqrlie.org> écrit:
|
| > | > 1 ? 0 : 1>>32
| > |
| > | L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi
| > | l'évaluer en tant que sous-expression constante (sans chercher à
| > | savoir si la valeur pourra être utilisée ou si elle ne sera jamais
| > | utilisée), et dans ce cas, il y a comportement indéfini.
|
| > Bah non ; ce n'est pas un comportement possible de la machine
| > abstraite.
|
| Sur quoi tu te bases?
| Dans l'article , | Gabriel Dos Reis écrit: | | > Vincent Lefevre <vincent+ writes: | | > | Dans l'article <cjvbua$f0p$, | > | Charlie Gordon écrit: | | > | > 1 ? 0 : 1>>32 | > | | > | L'implémentation peut ne pas évaluer 1>>32. Mais elle peut aussi | > | l'évaluer en tant que sous-expression constante (sans chercher à | > | savoir si la valeur pourra être utilisée ou si elle ne sera jamais | > | utilisée), et dans ce cas, il y a comportement indéfini. | | > Bah non ; ce n'est pas un comportement possible de la machine | > abstraite. | | Sur quoi tu te bases?
Le machin que tu cites à tout le monde.
-- Gaby
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:
| Dans l'article <ck3i0s$2r0$, | Antoine Leca écrit: | | > En 20041007115911$, Vincent Lefevre va escriure: | > > Dans l'article <ck0fuf$q8h$, | > > Antoine Leca écrit: | > > | > >> Autrement dit, si le comportement indéfini est dans du code non | > >> évalué, [...] | > > | > > Mais si le comportement indéfini est dans du code évalué à la | > > traduction (cf 6.6#2, ce qui est le cas qui me préoccupe)? | | > Est-il évalué, ou non ? | | Il est très probablement évalué à la traduction
Pourquoi faire ?
| (c'est une optimisation).
Une optimisation ne change pas le fonctionnement observable.
-- Gaby
Vincent Lefevre <vincent+news@vinc17.org> writes:
| Dans l'article <ck3i0s$2r0$1@shakotay.alphanet.ch>,
| Antoine Leca <root@localhost.gov> écrit:
|
| > En 20041007115911$0fba@vinc17.org, Vincent Lefevre va escriure:
| > > Dans l'article <ck0fuf$q8h$1@shakotay.alphanet.ch>,
| > > Antoine Leca <root@localhost.gov> écrit:
| > >
| > >> Autrement dit, si le comportement indéfini est dans du code non
| > >> évalué, [...]
| > >
| > > Mais si le comportement indéfini est dans du code évalué à la
| > > traduction (cf 6.6#2, ce qui est le cas qui me préoccupe)?
|
| > Est-il évalué, ou non ?
|
| Il est très probablement évalué à la traduction
Pourquoi faire ?
| (c'est une optimisation).
Une optimisation ne change pas le fonctionnement observable.
| Dans l'article <ck3i0s$2r0$, | Antoine Leca écrit: | | > En 20041007115911$, Vincent Lefevre va escriure: | > > Dans l'article <ck0fuf$q8h$, | > > Antoine Leca écrit: | > > | > >> Autrement dit, si le comportement indéfini est dans du code non | > >> évalué, [...] | > > | > > Mais si le comportement indéfini est dans du code évalué à la | > > traduction (cf 6.6#2, ce qui est le cas qui me préoccupe)? | | > Est-il évalué, ou non ? | | Il est très probablement évalué à la traduction
Pourquoi faire ?
| (c'est une optimisation).
Une optimisation ne change pas le fonctionnement observable.
-- Gaby
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:
| Dans l'article <ck3m5s$p4c$, | Antoine Leca écrit: | | > Je parlais d'évaluation au sens de la norme. | > 6.5.15p4: "The first operand is evaluated; there is a sequence point | > after its evaluation. The second operand is evaluated *only* if | > [...]" (c'est moi qui souligne). | | > Autrement dit, dans l'expression ternaire, exactement deux | > sous-expressions sont _évaluées_, l'autre ne l'est pas. | | Ça, c'est le cas général à l'exécution.
Oui et c'est ce qui compte.
Si tu as un compilateur qui fait autre chose, rapporte-le à celui qui t'a berné.
-- Gaby
Vincent Lefevre <vincent+news@vinc17.org> writes:
| Dans l'article <ck3m5s$p4c$1@shakotay.alphanet.ch>,
| Antoine Leca <root@localhost.gov> écrit:
|
| > Je parlais d'évaluation au sens de la norme.
| > 6.5.15p4: "The first operand is evaluated; there is a sequence point
| > after its evaluation. The second operand is evaluated *only* if
| > [...]" (c'est moi qui souligne).
|
| > Autrement dit, dans l'expression ternaire, exactement deux
| > sous-expressions sont _évaluées_, l'autre ne l'est pas.
|
| Ça, c'est le cas général à l'exécution.
Oui et c'est ce qui compte.
Si tu as un compilateur qui fait autre chose, rapporte-le à celui qui
t'a berné.
| Dans l'article <ck3m5s$p4c$, | Antoine Leca écrit: | | > Je parlais d'évaluation au sens de la norme. | > 6.5.15p4: "The first operand is evaluated; there is a sequence point | > after its evaluation. The second operand is evaluated *only* if | > [...]" (c'est moi qui souligne). | | > Autrement dit, dans l'expression ternaire, exactement deux | > sous-expressions sont _évaluées_, l'autre ne l'est pas. | | Ça, c'est le cas général à l'exécution.
Oui et c'est ce qui compte.
Si tu as un compilateur qui fait autre chose, rapporte-le à celui qui t'a berné.
-- Gaby
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:
| Dans l'article <cjvb19$d09$, | Charlie Gordon écrit: | | > "Vincent Lefevre" <vincent+ wrote in message | > news:20041005221856$ | | > > Il l'est. Le test n'a aucun influence ici. Le compilo peut très | > > bien évaluer des expressions au moment de la traduction (cas des | > > expressions constantes). Comme pour chaque valeur du terme de | > > gauche il y a comportement indéfini, l'implémentation peut faire | > > ce qu'elle veut, à savoir, considérer que la valeur est constante. | > > Dans ce cas, toutes les contraintes du 6.6 sont satisfaites. | | > Pas du tout ! C'est le code produit qui a un comportement indéfini, | > pas le compilateur. | | Je n'ai pas dit que le compilateur avait un comportement indéfini, | mais qu'elle avait le droit de faire ce qu'elle veut concernant la | traduction du code en question.
c'est du n'importe quoi.
-- Gaby
Vincent Lefevre <vincent+news@vinc17.org> writes:
| Dans l'article <cjvb19$d09$1@news.tiscali.fr>,
| Charlie Gordon <news@chqrlie.org> écrit:
|
| > "Vincent Lefevre" <vincent+news@vinc17.org> wrote in message
| > news:20041005221856$0b97@vinc17.org...
|
| > > Il l'est. Le test n'a aucun influence ici. Le compilo peut très
| > > bien évaluer des expressions au moment de la traduction (cas des
| > > expressions constantes). Comme pour chaque valeur du terme de
| > > gauche il y a comportement indéfini, l'implémentation peut faire
| > > ce qu'elle veut, à savoir, considérer que la valeur est constante.
| > > Dans ce cas, toutes les contraintes du 6.6 sont satisfaites.
|
| > Pas du tout ! C'est le code produit qui a un comportement indéfini,
| > pas le compilateur.
|
| Je n'ai pas dit que le compilateur avait un comportement indéfini,
| mais qu'elle avait le droit de faire ce qu'elle veut concernant la
| traduction du code en question.
| Dans l'article <cjvb19$d09$, | Charlie Gordon écrit: | | > "Vincent Lefevre" <vincent+ wrote in message | > news:20041005221856$ | | > > Il l'est. Le test n'a aucun influence ici. Le compilo peut très | > > bien évaluer des expressions au moment de la traduction (cas des | > > expressions constantes). Comme pour chaque valeur du terme de | > > gauche il y a comportement indéfini, l'implémentation peut faire | > > ce qu'elle veut, à savoir, considérer que la valeur est constante. | > > Dans ce cas, toutes les contraintes du 6.6 sont satisfaites. | | > Pas du tout ! C'est le code produit qui a un comportement indéfini, | > pas le compilateur. | | Je n'ai pas dit que le compilateur avait un comportement indéfini, | mais qu'elle avait le droit de faire ce qu'elle veut concernant la | traduction du code en question.
c'est du n'importe quoi.
-- Gaby
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:
| Dans l'article , | Jean-Marc Bourguet écrit: | | > Pourquoi? En supposant l'absence de bit de padding le decalage n'est | > pas evalue dans sauf si le compilateur peut montrer qu'il n'a pas | > d'effet. Meme si ce n'etait pas le cas, le compilateur qui genere du | > comportement indefini mechant pour ca dans le cas ou (c) est une | > constante est de toute maniere bon a jeter. | | Le problème est l'évaluation (au moment de la traduction) d'une | constante dont le résultat est indéfini.
Mais c'est n'importe quoi.
-- Gaby
Vincent Lefevre <vincent+news@vinc17.org> writes:
| Dans l'article <pxb1xgc5p7w.fsf@news.bourguet.org>,
| Jean-Marc Bourguet <jm@bourguet.org> écrit:
|
| > Pourquoi? En supposant l'absence de bit de padding le decalage n'est
| > pas evalue dans sauf si le compilateur peut montrer qu'il n'a pas
| > d'effet. Meme si ce n'etait pas le cas, le compilateur qui genere du
| > comportement indefini mechant pour ca dans le cas ou (c) est une
| > constante est de toute maniere bon a jeter.
|
| Le problème est l'évaluation (au moment de la traduction) d'une
| constante dont le résultat est indéfini.
| Dans l'article , | Jean-Marc Bourguet écrit: | | > Pourquoi? En supposant l'absence de bit de padding le decalage n'est | > pas evalue dans sauf si le compilateur peut montrer qu'il n'a pas | > d'effet. Meme si ce n'etait pas le cas, le compilateur qui genere du | > comportement indefini mechant pour ca dans le cas ou (c) est une | > constante est de toute maniere bon a jeter. | | Le problème est l'évaluation (au moment de la traduction) d'une | constante dont le résultat est indéfini.
Mais c'est n'importe quoi.
-- Gaby
Charlie Gordon
"Vincent Lefevre" <vincent+ wrote in message news:20041007120136$
Je n'ai pas dit cela. Attention, je ne me fixe pas sur une implémentation particulière. Par exemple, si quelqu'un écrit
int main(void) { return 1 >> 32; }
avec certaines (de nombreuses) implémentations, ça va toujours fonctionner, mais ce n'est pas du tout portable. Un warning me semble donc justifié ...
Un warning pour le code en question est justifié sur les plateformes 32 bits, d'ailleurs ce pourrait etre une erreur. Par contre le code suivant n'a aucune raison de déclencher un warning :
1 ? 1 : 1 >> 32;
Enfin sur une plateforme 64 bits avec des int de 64 bits, 1 >> 32 ne doit déclencher un warning que si l'on recherche la portabilité. Imagine la quantité de warning que déclencherait n'importe quel bout de code non trivial si le compilo mettait systematiquement en garde sur les problèmes de portabilité 16 bits...
Quels sont les outils qui détectent les constructions non portables, en fonction d'un ensemble de cibles spécifié : 16, 32, 64, LE, BE, int!=long, pointeurs!=int, pointeurs data!=pointeurs code, float/double, size_t!=unsigned int, et des tas d'autres ?
Chqrlie.
"Vincent Lefevre" <vincent+news@vinc17.org> wrote in message
news:20041007120136$0871@vinc17.org...
Je n'ai pas dit cela. Attention, je ne me fixe pas sur une
implémentation particulière. Par exemple, si quelqu'un écrit
int main(void)
{
return 1 >> 32;
}
avec certaines (de nombreuses) implémentations, ça va toujours
fonctionner, mais ce n'est pas du tout portable. Un warning me
semble donc justifié ...
Un warning pour le code en question est justifié sur les plateformes 32
bits, d'ailleurs ce pourrait etre une erreur.
Par contre le code suivant n'a aucune raison de déclencher un warning :
1 ? 1 : 1 >> 32;
Enfin sur une plateforme 64 bits avec des int de 64 bits, 1 >> 32 ne doit
déclencher un warning que si l'on recherche la portabilité.
Imagine la quantité de warning que déclencherait n'importe quel bout de code
non trivial si le compilo mettait systematiquement en garde sur les
problèmes de portabilité 16 bits...
Quels sont les outils qui détectent les constructions non portables, en
fonction d'un ensemble de cibles spécifié : 16, 32, 64, LE, BE, int!=long,
pointeurs!=int, pointeurs data!=pointeurs code, float/double,
size_t!=unsigned int, et des tas d'autres ?
"Vincent Lefevre" <vincent+ wrote in message news:20041007120136$
Je n'ai pas dit cela. Attention, je ne me fixe pas sur une implémentation particulière. Par exemple, si quelqu'un écrit
int main(void) { return 1 >> 32; }
avec certaines (de nombreuses) implémentations, ça va toujours fonctionner, mais ce n'est pas du tout portable. Un warning me semble donc justifié ...
Un warning pour le code en question est justifié sur les plateformes 32 bits, d'ailleurs ce pourrait etre une erreur. Par contre le code suivant n'a aucune raison de déclencher un warning :
1 ? 1 : 1 >> 32;
Enfin sur une plateforme 64 bits avec des int de 64 bits, 1 >> 32 ne doit déclencher un warning que si l'on recherche la portabilité. Imagine la quantité de warning que déclencherait n'importe quel bout de code non trivial si le compilo mettait systematiquement en garde sur les problèmes de portabilité 16 bits...
Quels sont les outils qui détectent les constructions non portables, en fonction d'un ensemble de cibles spécifié : 16, 32, 64, LE, BE, int!=long, pointeurs!=int, pointeurs data!=pointeurs code, float/double, size_t!=unsigned int, et des tas d'autres ?
Chqrlie.
Charlie Gordon
"Vincent Lefevre" <vincent+ wrote in message news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de la cross-compilation) ?
#if (2 << 15) == 0 // ici en est sur une plateforme 16 bits, definir la macro qui va bien #elif (2 << 31) == 0 // ici les entiers sont sur 32 bits : autre version #else //... etc #endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche, mais restreignons nous à la norme.
Chqrlie.
"Vincent Lefevre" <vincent+news@vinc17.org> wrote in message
news:20041004141107$69dc@vinc17.org...
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de
la cross-compilation) ?
#if (2 << 15) == 0
// ici en est sur une plateforme 16 bits, definir la macro qui va bien
#elif (2 << 31) == 0
// ici les entiers sont sur 32 bits : autre version
#else
//... etc
#endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche,
mais restreignons nous à la norme.
"Vincent Lefevre" <vincent+ wrote in message news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de la cross-compilation) ?
#if (2 << 15) == 0 // ici en est sur une plateforme 16 bits, definir la macro qui va bien #elif (2 << 31) == 0 // ici les entiers sont sur 32 bits : autre version #else //... etc #endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche, mais restreignons nous à la norme.
Chqrlie.
Laurent Deniau
Charlie Gordon wrote:
"Vincent Lefevre" <vincent+ wrote in message news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de la cross-compilation) ?
#if (2 << 15) == 0 // ici en est sur une plateforme 16 bits, definir la macro qui va bien #elif (2 << 31) == 0 // ici les entiers sont sur 32 bits : autre version #else //... etc #endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche, mais restreignons nous à la norme.
non (6.10.1-3) parce que le preprocesseur travaille sur intmax_t (ou uintmax_t) qui peuvent etre plus grand que int ou long puisque c'est le plus grand type intregral supporte par le compilateur. Donc ce que tu testes, c'est la taille de intmax_t pas celle de int ou long. Cela pose aussi le probleme de la cross-compilation.
a+, ld.
Charlie Gordon wrote:
"Vincent Lefevre" <vincent+news@vinc17.org> wrote in message
news:20041004141107$69dc@vinc17.org...
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de
la cross-compilation) ?
#if (2 << 15) == 0
// ici en est sur une plateforme 16 bits, definir la macro qui va bien
#elif (2 << 31) == 0
// ici les entiers sont sur 32 bits : autre version
#else
//... etc
#endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche,
mais restreignons nous à la norme.
non (6.10.1-3) parce que le preprocesseur travaille sur intmax_t (ou
uintmax_t) qui peuvent etre plus grand que int ou long puisque c'est le
plus grand type intregral supporte par le compilateur. Donc ce que tu
testes, c'est la taille de intmax_t pas celle de int ou long. Cela pose
aussi le probleme de la cross-compilation.
"Vincent Lefevre" <vincent+ wrote in message news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
Une nouvelle piste à explorer pour ce thread déjà bien fourni :
Pourrait-on utiliser le préprocesseur de cette facon (en excluant le cas de la cross-compilation) ?
#if (2 << 15) == 0 // ici en est sur une plateforme 16 bits, definir la macro qui va bien #elif (2 << 31) == 0 // ici les entiers sont sur 32 bits : autre version #else //... etc #endif
Je peux imaginer des tonnes d'arguments pour interdire une telle approche, mais restreignons nous à la norme.
non (6.10.1-3) parce que le preprocesseur travaille sur intmax_t (ou uintmax_t) qui peuvent etre plus grand que int ou long puisque c'est le plus grand type intregral supporte par le compilateur. Donc ce que tu testes, c'est la taille de intmax_t pas celle de int ou long. Cela pose aussi le probleme de la cross-compilation.