Si ton sentiment est confirmé, ça remet en cause le miens. Ce type d'union est pas mal utilisé pour faciliter la manipulation des octets d'une donnée quelconque.
Par qui ? C'est un comportement indéfini de lire un élément de l'union autre que le dernier qu'on a écrit. Ça l'a toujours été, et en général, ça ne marche pas avec beaucoup de compilateurs ; par exemple, le compilateur voit que la valeur écrite dan mon_t.l n'est jamais utilisée, et supprime l'écriture.
J'ai deux exemples en tête. Un ancien, du temps de DOS, pour la représentation des registres du CPU:
union REGS { struct WORDREGS x; struct BYTEREGS h; };
exemple d'utilisation: http://perso.wanadoo.fr/olivier.lalorette/sys.htm
Note bien en revanche qu'il s'agit ici d'un comportement indéfini par la norme -- ce qui est un peu normal -- puisqu'en fait, tu es en train de préparer des données pour l'assembleur. (En ce qui concerne la norme, un compilateur est bien libre aussi de mettre des octets de rembourage dans le struct BYTEREGS. Ce qui ferait que ah coïncide avec le poids faible de bx. Mais évidemment, celui qui a créé ces struct et cette union sait bien que le compilateur en question ne le faisait pas.)
ou plus récent, dans le monde Windows, le type LARGE_INTEGER:
typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER, *PLARGE_INTEGER;
Tu as dû perdre un nom quelque part en copiant. Tel que c'est écrit, la première struct ne sert à rien -- je crois que le code n'est même pas légal.
En supposant un nom derrière la première struct : sans savoir ce que sont DWORD et LONG, c'est difficile à saisir ce qui se passe ici. Mais j'ai comme une doute qu'il s'agit aussi d'un comportement indéfini par la norme, défini en revanche dans une certaine impémentation pour qui sait quelle raison.
Utilisé par SetFilePointerEx par exemple (equivalent de seek): http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
-- James Kanze Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Aurelien Regat-Barrel wrote:
Si ton sentiment est confirmé, ça remet en cause le miens.
Ce type d'union est pas mal utilisé pour faciliter la
manipulation des octets d'une donnée quelconque.
Par qui ? C'est un comportement indéfini de lire un élément
de l'union autre que le dernier qu'on a écrit. Ça l'a
toujours été, et en général, ça ne marche pas avec beaucoup
de compilateurs ; par exemple, le compilateur voit que la
valeur écrite dan mon_t.l n'est jamais utilisée, et supprime
l'écriture.
J'ai deux exemples en tête. Un ancien, du temps de DOS, pour
la représentation des registres du CPU:
union REGS {
struct WORDREGS x;
struct BYTEREGS h;
};
exemple d'utilisation:
http://perso.wanadoo.fr/olivier.lalorette/sys.htm
Note bien en revanche qu'il s'agit ici d'un comportement
indéfini par la norme -- ce qui est un peu normal -- puisqu'en
fait, tu es en train de préparer des données pour l'assembleur.
(En ce qui concerne la norme, un compilateur est bien libre
aussi de mettre des octets de rembourage dans le struct
BYTEREGS. Ce qui ferait que ah coïncide avec le poids faible de
bx. Mais évidemment, celui qui a créé ces struct et cette union
sait bien que le compilateur en question ne le faisait pas.)
ou plus récent, dans le monde Windows, le type LARGE_INTEGER:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart; } u;
LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;
Tu as dû perdre un nom quelque part en copiant. Tel que c'est
écrit, la première struct ne sert à rien -- je crois que le code
n'est même pas légal.
En supposant un nom derrière la première struct : sans savoir ce
que sont DWORD et LONG, c'est difficile à saisir ce qui se passe
ici. Mais j'ai comme une doute qu'il s'agit aussi d'un
comportement indéfini par la norme, défini en revanche dans une
certaine impémentation pour qui sait quelle raison.
Utilisé par SetFilePointerEx par exemple (equivalent de seek):
http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos
C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un
compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue
qu'une saloperie comme ça ne me donne pas envie de programmer
pour le système.)
--
James Kanze kanze.james@neuf.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Si ton sentiment est confirmé, ça remet en cause le miens. Ce type d'union est pas mal utilisé pour faciliter la manipulation des octets d'une donnée quelconque.
Par qui ? C'est un comportement indéfini de lire un élément de l'union autre que le dernier qu'on a écrit. Ça l'a toujours été, et en général, ça ne marche pas avec beaucoup de compilateurs ; par exemple, le compilateur voit que la valeur écrite dan mon_t.l n'est jamais utilisée, et supprime l'écriture.
J'ai deux exemples en tête. Un ancien, du temps de DOS, pour la représentation des registres du CPU:
union REGS { struct WORDREGS x; struct BYTEREGS h; };
exemple d'utilisation: http://perso.wanadoo.fr/olivier.lalorette/sys.htm
Note bien en revanche qu'il s'agit ici d'un comportement indéfini par la norme -- ce qui est un peu normal -- puisqu'en fait, tu es en train de préparer des données pour l'assembleur. (En ce qui concerne la norme, un compilateur est bien libre aussi de mettre des octets de rembourage dans le struct BYTEREGS. Ce qui ferait que ah coïncide avec le poids faible de bx. Mais évidemment, celui qui a créé ces struct et cette union sait bien que le compilateur en question ne le faisait pas.)
ou plus récent, dans le monde Windows, le type LARGE_INTEGER:
typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER, *PLARGE_INTEGER;
Tu as dû perdre un nom quelque part en copiant. Tel que c'est écrit, la première struct ne sert à rien -- je crois que le code n'est même pas légal.
En supposant un nom derrière la première struct : sans savoir ce que sont DWORD et LONG, c'est difficile à saisir ce qui se passe ici. Mais j'ai comme une doute qu'il s'agit aussi d'un comportement indéfini par la norme, défini en revanche dans une certaine impémentation pour qui sait quelle raison.
Utilisé par SetFilePointerEx par exemple (equivalent de seek): http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
-- James Kanze Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Fabien LE LEZ
On Sun, 09 Apr 2006 20:21:42 +0200, James Kanze :
(Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout le monde : encapsuler les saloperies qui te sont indispensables (et Dieu sait qu'il y en a un paquet !), histoire de pouvoir programmer proprement dans le reste du code...
On Sun, 09 Apr 2006 20:21:42 +0200, James Kanze <kanze.james@neuf.fr>:
(Mais j'avoue
qu'une saloperie comme ça ne me donne pas envie de programmer
pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout le
monde : encapsuler les saloperies qui te sont indispensables (et Dieu
sait qu'il y en a un paquet !), histoire de pouvoir programmer
proprement dans le reste du code...
(Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout le monde : encapsuler les saloperies qui te sont indispensables (et Dieu sait qu'il y en a un paquet !), histoire de pouvoir programmer proprement dans le reste du code...
kanze
Fabien LE LEZ wrote:
On Sun, 09 Apr 2006 20:21:42 +0200, James Kanze :
(Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout le monde : encapsuler les saloperies qui te sont indispensables (et Dieu sait qu'il y en a un paquet !), histoire de pouvoir programmer proprement dans le reste du code...
En somme, comme on fait pour Unix. (Je ne me rappelle pas d'avoir vue quelque chose d'aussi affreux sous Unix, mais il y a bien des choses qu'on préfèrerait ne pas voir quand même.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Fabien LE LEZ wrote:
On Sun, 09 Apr 2006 20:21:42 +0200, James Kanze <kanze.james@neuf.fr>:
(Mais j'avoue
qu'une saloperie comme ça ne me donne pas envie de programmer
pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout
le monde : encapsuler les saloperies qui te sont
indispensables (et Dieu sait qu'il y en a un paquet !),
histoire de pouvoir programmer proprement dans le reste du
code...
En somme, comme on fait pour Unix. (Je ne me rappelle pas
d'avoir vue quelque chose d'aussi affreux sous Unix, mais il y a
bien des choses qu'on préfèrerait ne pas voir quand même.)
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
(Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Ben... si tu dois programmer sous Windows, tu feras comme tout le monde : encapsuler les saloperies qui te sont indispensables (et Dieu sait qu'il y en a un paquet !), histoire de pouvoir programmer proprement dans le reste du code...
En somme, comme on fait pour Unix. (Je ne me rappelle pas d'avoir vue quelque chose d'aussi affreux sous Unix, mais il y a bien des choses qu'on préfèrerait ne pas voir quand même.)
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aurelien Regat-Barrel
ou plus récent, dans le monde Windows, le type LARGE_INTEGER:
typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; }; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER, *PLARGE_INTEGER;
Tu as dû perdre un nom quelque part en copiant. Tel que c'est écrit, la première struct ne sert à rien -- je crois que le code n'est même pas légal.
Non, je n'ai rien oublié. C'est juste que le compilo de MS permettait de définir des structs (et même des unions) anonymes. Je suppose qu'à la base il ne devait y avoir que la première struct (anonyme), et qu'il ont rajouté la seconde (identique mais nommée) pour que ce soit un peu plus conforme à la norme, tout en laissant la struct anonyme pour compatibilité ascendante. MingW définit LARGE_INTEGER ainsi:
En supposant un nom derrière la première struct : sans savoir ce que sont DWORD et LONG, c'est difficile à saisir ce qui se passe ici.
typedef unsigned long DWORD; typedef long LONG; typedef __int64 LONGLONG;
Mais j'ai comme une doute qu'il s'agit aussi d'un comportement indéfini par la norme, défini en revanche dans une certaine impémentation pour qui sait quelle raison.
La doc de LARGE_INTERGER semble expliquer que ce type sert à manipuler des entiers bits avec des compilateurs qui ne disposent que d'entiers 32 bits.
Je modifie ma question. Si j'ai ceci:
union union_t { int i; };
je peux caster comme en suivant ?
int n = 10; union_t *u = reinterpret_cast<union_t*>( &n ); std::cout << u->i;
Utilisé par SetFilePointerEx par exemple (equivalent de seek): http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de te causer un infarctus:
Tu as dû perdre un nom quelque part en copiant. Tel que c'est
écrit, la première struct ne sert à rien -- je crois que le code
n'est même pas légal.
Non, je n'ai rien oublié. C'est juste que le compilo de MS permettait de
définir des structs (et même des unions) anonymes. Je suppose qu'à la
base il ne devait y avoir que la première struct (anonyme), et qu'il ont
rajouté la seconde (identique mais nommée) pour que ce soit un peu plus
conforme à la norme, tout en laissant la struct anonyme pour
compatibilité ascendante.
MingW définit LARGE_INTEGER ainsi:
En supposant un nom derrière la première struct : sans savoir ce
que sont DWORD et LONG, c'est difficile à saisir ce qui se passe
ici.
typedef unsigned long DWORD;
typedef long LONG;
typedef __int64 LONGLONG;
Mais j'ai comme une doute qu'il s'agit aussi d'un
comportement indéfini par la norme, défini en revanche dans une
certaine impémentation pour qui sait quelle raison.
La doc de LARGE_INTERGER semble expliquer que ce type sert à manipuler
des entiers bits avec des compilateurs qui ne disposent que d'entiers 32
bits.
Je modifie ma question. Si j'ai ceci:
union union_t
{
int i;
};
je peux caster comme en suivant ?
int n = 10;
union_t *u = reinterpret_cast<union_t*>( &n );
std::cout << u->i;
Utilisé par SetFilePointerEx par exemple (equivalent de seek):
http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos
C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un
compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue
qu'une saloperie comme ça ne me donne pas envie de programmer
pour le système.)
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de
te causer un infarctus:
Tu as dû perdre un nom quelque part en copiant. Tel que c'est écrit, la première struct ne sert à rien -- je crois que le code n'est même pas légal.
Non, je n'ai rien oublié. C'est juste que le compilo de MS permettait de définir des structs (et même des unions) anonymes. Je suppose qu'à la base il ne devait y avoir que la première struct (anonyme), et qu'il ont rajouté la seconde (identique mais nommée) pour que ce soit un peu plus conforme à la norme, tout en laissant la struct anonyme pour compatibilité ascendante. MingW définit LARGE_INTEGER ainsi:
En supposant un nom derrière la première struct : sans savoir ce que sont DWORD et LONG, c'est difficile à saisir ce qui se passe ici.
typedef unsigned long DWORD; typedef long LONG; typedef __int64 LONGLONG;
Mais j'ai comme une doute qu'il s'agit aussi d'un comportement indéfini par la norme, défini en revanche dans une certaine impémentation pour qui sait quelle raison.
La doc de LARGE_INTERGER semble expliquer que ce type sert à manipuler des entiers bits avec des compilateurs qui ne disposent que d'entiers 32 bits.
Je modifie ma question. Si j'ai ceci:
union union_t { int i; };
je peux caster comme en suivant ?
int n = 10; union_t *u = reinterpret_cast<union_t*>( &n ); std::cout << u->i;
Utilisé par SetFilePointerEx par exemple (equivalent de seek): http://msdn.microsoft.com/library/en-us/fileio/fs/setfilepointer.asp
Le type LARGE_INTEGER est utilisé par de nombreux compilos C/C++ sous Windows, et je pense que ça marche à chaque fois.
Si ça fait partie de l'API du système, effectivement, un compilateur n'oserait pas ne pas le faire marcher. (Mais j'avoue qu'une saloperie comme ça ne me donne pas envie de programmer pour le système.)
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de te causer un infarctus:
Pour moi l'union c'est (entre autre) un autre moyen de faire du cast.
Ben non. Un union est juste un moyen d'économiser de la place, quand on sait qu'à un moment donné d'un programme, on n'utilisera qu'une partie des membres. En fait, "union" n'est rien d'autre qu'une optimisation. Si, en remplaçant "union" par "struct" partout dans ton code, le sens du programme change, il y a des chances pour que ton code de départ ait un comportement indéfini.
Je savais pas.
Par ailleurs, quand tu écris :
union union_t { struct s { short low; short high; } u; long l; };
tu as l'air de penser que sizeof(union_t::s)==sizeof(long). Y a-t-il un argument qui justifierait cela ?
Un padding à zéro (#pragma pack...) ?
-- Aurélien Regat-Barrel
Pour moi
l'union c'est (entre autre) un autre moyen de faire du cast.
Ben non. Un union est juste un moyen d'économiser de la place, quand
on sait qu'à un moment donné d'un programme, on n'utilisera qu'une
partie des membres.
En fait, "union" n'est rien d'autre qu'une optimisation. Si, en
remplaçant "union" par "struct" partout dans ton code, le sens du
programme change, il y a des chances pour que ton code de départ ait
un comportement indéfini.
Je savais pas.
Par ailleurs, quand tu écris :
union union_t {
struct s {
short low;
short high;
} u;
long l;
};
tu as l'air de penser que sizeof(union_t::s)==sizeof(long).
Y a-t-il un argument qui justifierait cela ?
Pour moi l'union c'est (entre autre) un autre moyen de faire du cast.
Ben non. Un union est juste un moyen d'économiser de la place, quand on sait qu'à un moment donné d'un programme, on n'utilisera qu'une partie des membres. En fait, "union" n'est rien d'autre qu'une optimisation. Si, en remplaçant "union" par "struct" partout dans ton code, le sens du programme change, il y a des chances pour que ton code de départ ait un comportement indéfini.
Je savais pas.
Par ailleurs, quand tu écris :
union union_t { struct s { short low; short high; } u; long l; };
tu as l'air de penser que sizeof(union_t::s)==sizeof(long). Y a-t-il un argument qui justifierait cela ?
Un padding à zéro (#pragma pack...) ?
-- Aurélien Regat-Barrel
Fabien LE LEZ
On Mon, 10 Apr 2006 09:50:38 +0200, Aurelien Regat-Barrel :
je peux caster comme en suivant ?
int n = 10; union_t *u = reinterpret_cast<union_t*>( &n ); std::cout << u->i;
En C++, non. Si maintenant tu fais du code spécifique à un compilo (ou quelques compilateurs), p'têt' ben qu'ça marche, p'têt' ben qu'ça marche pas. Faut voir la doc du/des compilo(s) en question.
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de te causer un infarctus:
Mon préféré est GetMessage() -- fonction utilisée, directement ou indirectement, par à peu près toutes les applications GUI sous Windows, et dont la doc indique :
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
Je me demande si ce truc a été proposé à l'IOCCC...
On Mon, 10 Apr 2006 09:50:38 +0200, Aurelien Regat-Barrel
<nospam.aregatba@yahoo.fr>:
je peux caster comme en suivant ?
int n = 10;
union_t *u = reinterpret_cast<union_t*>( &n );
std::cout << u->i;
En C++, non.
Si maintenant tu fais du code spécifique à un compilo (ou quelques
compilateurs), p'têt' ben qu'ça marche, p'têt' ben qu'ça marche pas.
Faut voir la doc du/des compilo(s) en question.
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de
te causer un infarctus:
Mon préféré est GetMessage() -- fonction utilisée, directement ou
indirectement, par à peu près toutes les applications GUI sous
Windows, et dont la doc indique :
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut :
If the function retrieves a message other than WM_QUIT, the
return value is nonzero.
If the function retrieves the WM_QUIT message, the return value
is zero.
If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur
int. Et, pour simplifier le tout, il me semble que stricto sensu, -1
est une valeur "nonzero".
Je me demande si ce truc a été proposé à l'IOCCC...
On Mon, 10 Apr 2006 09:50:38 +0200, Aurelien Regat-Barrel :
je peux caster comme en suivant ?
int n = 10; union_t *u = reinterpret_cast<union_t*>( &n ); std::cout << u->i;
En C++, non. Si maintenant tu fais du code spécifique à un compilo (ou quelques compilateurs), p'têt' ben qu'ça marche, p'têt' ben qu'ça marche pas. Faut voir la doc du/des compilo(s) en question.
Si une petite union comme ça te fait hérisser le poil, VARIANT risque de te causer un infarctus:
Mon préféré est GetMessage() -- fonction utilisée, directement ou indirectement, par à peu près toutes les applications GUI sous Windows, et dont la doc indique :
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
Je me demande si ce truc a été proposé à l'IOCCC...
Sylvain
Fabien LE LEZ wrote on 10/04/2006 10:05:
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
btw, en effet -1 est "nonzero", le contraire n'est ni indiqué, ni sous-entendu.
Sylvain.
Fabien LE LEZ wrote on 10/04/2006 10:05:
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut :
If the function retrieves a message other than WM_QUIT, the
return value is nonzero.
If the function retrieves the WM_QUIT message, the return value
is zero.
If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur
int. Et, pour simplifier le tout, il me semble que stricto sensu, -1
est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit
modifié pour permettre la distinction d'erreur sévère, passons.
btw, en effet -1 est "nonzero", le contraire n'est ni indiqué, ni
sous-entendu.
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
btw, en effet -1 est "nonzero", le contraire n'est ni indiqué, ni sous-entendu.
Sylvain.
Loïc Joly
Fabien LE LEZ wrote on 10/04/2006 10:05:
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1. Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
-- Loïc
Fabien LE LEZ wrote on 10/04/2006 10:05:
BOOL GetMessage (...)
La valeur de retour, de type BOOL, vaut :
If the function retrieves a message other than WM_QUIT, the
return value is nonzero.
If the function retrieves the WM_QUIT message, the return value
is zero. If there is an error, the return value is -1.
Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur
int. Et, pour simplifier le tout, il me semble que stricto sensu, -1
est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit
modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un
DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et
ne devrait pas casser de code existant.
La valeur de retour, de type BOOL, vaut : If the function retrieves a message other than WM_QUIT, the return value is nonzero. If the function retrieves the WM_QUIT message, the return value is zero. If there is an error, the return value is -1. Bien évidemment, pour que ça marche, "BOOL" est en fait un typedef sur int. Et, pour simplifier le tout, il me semble que stricto sensu, -1 est une valeur "nonzero".
drole de façon de (ré)inventer l'histoire ?!
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
-- Loïc
Sylvain
Loïc Joly wrote on 10/04/2006 23:31:
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une différence.
modifier le type retour d'une API préhistorique n'aurait pas été imaginable (problème de compatibilité asc. même si l'impact est ici assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
il aurait été plus propre d'avoir un GetMessageEx(...) qui lui (et lui seul) aurait traité des erreurs critiques; mais M$ a ses raisons que la raison et l'élégance souvent ignorent.
Sylvain.
Loïc Joly wrote on 10/04/2006 23:31:
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne
soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un
DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et
ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier
signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une
différence.
modifier le type retour d'une API préhistorique n'aurait pas été
imaginable (problème de compatibilité asc. même si l'impact est ici
assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
il aurait été plus propre d'avoir un GetMessageEx(...) qui lui (et lui
seul) aurait traité des erreurs critiques; mais M$ a ses raisons que la
raison et l'élégance souvent ignorent.
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une différence.
modifier le type retour d'une API préhistorique n'aurait pas été imaginable (problème de compatibilité asc. même si l'impact est ici assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
il aurait été plus propre d'avoir un GetMessageEx(...) qui lui (et lui seul) aurait traité des erreurs critiques; mais M$ a ses raisons que la raison et l'élégance souvent ignorent.
Sylvain.
Loïc Joly
Loïc Joly wrote on 10/04/2006 23:31:
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une différence.
Oups, pas fais gaffe à l'aspect signé. INT alors.
modifier le type retour d'une API préhistorique n'aurait pas été imaginable (problème de compatibilité asc. même si l'impact est ici assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
Vu que INT et BOOL sont définis de même manière, je ne vois aucun impact pour les utilisateurs.
-- Loïc
Loïc Joly wrote on 10/04/2006 23:31:
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne
soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un
DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et
ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier
signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une
différence.
Oups, pas fais gaffe à l'aspect signé. INT alors.
modifier le type retour d'une API préhistorique n'aurait pas été
imaginable (problème de compatibilité asc. même si l'impact est ici
assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
Vu que INT et BOOL sont définis de même manière, je ne vois aucun impact
pour les utilisateurs.
le type BOOL existe depuis windows 1.0 bien avant que GetMessage ne soit modifié pour permettre la distinction d'erreur sévère, passons.
Pourquoi ne pas modifier la fonction pour qu'elle retourne un int (un DWORD) dans ce cas ? Ca éviterai d'induire l'utilisateur en erreur, et ne devrait pas casser de code existant.
un "int" (type aliasé par "BOOL") est sur Intel 32 bits un type entier signé sur 32 bits, un DWORD est un "unsigned long", ça fait déjà une différence.
Oups, pas fais gaffe à l'aspect signé. INT alors.
modifier le type retour d'une API préhistorique n'aurait pas été imaginable (problème de compatibilité asc. même si l'impact est ici assez faible, pas pire que le fait de ne pas traiter ces retours négatifs).
Vu que INT et BOOL sont définis de même manière, je ne vois aucun impact pour les utilisateurs.