Bonjour,
Il est fréquent que des variables (de tous types) soient initialisées
par la lecture d'un fichier INI par exemple, voire un calcul ou
l'appel d'une fonction en début de programme.
Il peut arriver que ces "constantes" soient modifiables
"exceptionnellement" par un utilisateur identifié (on peut alors se
ramener au précédent, par clôture/initialisation).
Il me semble normal de conserver le statut const à ces variables. Pour
l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce
petit problème.
--
Merci,
Bonjour, Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce petit problème. Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ; - Modification uniquement par des fonctions membres de la classe (peut-être uniquement le constructeur) ; - Les accéder par des fonctions membres qualifiées 'const' et qui renvoient les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons.
À + Falk
Pierre Maurette wrote:
Bonjour,
Il est fréquent que des variables (de tous types) soient initialisées
par la lecture d'un fichier INI par exemple, voire un calcul ou
l'appel d'une fonction en début de programme.
Il peut arriver que ces "constantes" soient modifiables
"exceptionnellement" par un utilisateur identifié (on peut alors se
ramener au précédent, par clôture/initialisation).
Il me semble normal de conserver le statut const à ces variables. Pour
l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce
petit problème.
Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ;
- Modification uniquement par des fonctions membres de la classe (peut-être
uniquement le constructeur) ;
- Les accéder par des fonctions membres qualifiées 'const' et qui renvoient
les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons.
Bonjour, Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce petit problème. Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ; - Modification uniquement par des fonctions membres de la classe (peut-être uniquement le constructeur) ; - Les accéder par des fonctions membres qualifiées 'const' et qui renvoient les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons.
À + Falk
Pierre Maurette
Falk Tannhäuser typa:
Pierre Maurette wrote:
Bonjour, Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce petit problème. Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ; - Modification uniquement par des fonctions membres de la classe (peut-être uniquement le constructeur) ; - Les accéder par des fonctions membres qualifiées 'const' et qui renvoient les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons. Merci.
En fait, je me mélangeais les neurones hors de toute situation réelle de programation avec des cast de const. Dans ma vrai vie, j'utilise C++Builder et un composant TDataModule en appliquant votre solution. -- Pierre
Bonjour,
Il est fréquent que des variables (de tous types) soient initialisées
par la lecture d'un fichier INI par exemple, voire un calcul ou
l'appel d'une fonction en début de programme.
Il peut arriver que ces "constantes" soient modifiables
"exceptionnellement" par un utilisateur identifié (on peut alors se
ramener au précédent, par clôture/initialisation).
Il me semble normal de conserver le statut const à ces variables. Pour
l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce
petit problème.
Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ;
- Modification uniquement par des fonctions membres de la classe (peut-être
uniquement le constructeur) ;
- Les accéder par des fonctions membres qualifiées 'const' et qui renvoient
les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons.
Merci.
En fait, je me mélangeais les neurones hors de toute situation réelle
de programation avec des cast de const.
Dans ma vrai vie, j'utilise C++Builder et un composant TDataModule en
appliquant votre solution.
--
Pierre
Bonjour, Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
J'aimerais connaître la stratégie des uns et des autres face à ce petit problème. Solution possible :
- Encapsuler ces variables dans une (des) classe(s) en les déclarant 'private' ; - Modification uniquement par des fonctions membres de la classe (peut-être uniquement le constructeur) ; - Les accéder par des fonctions membres qualifiées 'const' et qui renvoient les contenues de ces variables soit par valeur, soit par référence sur 'const'.
Le cas échéant, ces classes devraient être des singletons. Merci.
En fait, je me mélangeais les neurones hors de toute situation réelle de programation avec des cast de const. Dans ma vrai vie, j'utilise C++Builder et un composant TDataModule en appliquant votre solution. -- Pierre
kanze
Pierre Maurette wrote in message news:...
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
En ce qui concerne les variables initialisées à partir des fichiers de configuration (.ini ou d'autres -- aussi depuis la registry sous Windows), j'utilise une classe singleton qui contient la configuration -- c-à-d que je lis le fichier une fois, et le maintient dans un std::set (ou un tableau haché). Normalement, l'interface du singleton ne donne pas d'accès en écriture aux éléments dans ce tableau ; pour le modifier, il faut appeler une fonction spécial avec le nom du fichier.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<jr6d80d3obj9eudc10gnvt56jhlaq8j52h@4ax.com>...
Il est fréquent que des variables (de tous types) soient initialisées
par la lecture d'un fichier INI par exemple, voire un calcul ou
l'appel d'une fonction en début de programme. Il peut arriver que ces
"constantes" soient modifiables "exceptionnellement" par un
utilisateur identifié (on peut alors se ramener au précédent, par
clôture/initialisation). Il me semble normal de conserver le statut
const à ces variables. Pour l'instant, j'utilise quelques cast, et ça
roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
En ce qui concerne les variables initialisées à partir des fichiers de
configuration (.ini ou d'autres -- aussi depuis la registry sous
Windows), j'utilise une classe singleton qui contient la
configuration -- c-à-d que je lis le fichier une fois, et le maintient
dans un std::set (ou un tableau haché). Normalement, l'interface du
singleton ne donne pas d'accès en écriture aux éléments dans ce
tableau ; pour le modifier, il faut appeler une fonction spécial avec le
nom du fichier.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
En ce qui concerne les variables initialisées à partir des fichiers de configuration (.ini ou d'autres -- aussi depuis la registry sous Windows), j'utilise une classe singleton qui contient la configuration -- c-à-d que je lis le fichier une fois, et le maintient dans un std::set (ou un tableau haché). Normalement, l'interface du singleton ne donne pas d'accès en écriture aux éléments dans ce tableau ; pour le modifier, il faut appeler une fonction spécial avec le nom du fichier.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Pierre Maurette
typa:
Pierre Maurette wrote in message news:...
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours. Je faisais parfois des trucs comme:
const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
En ce qui concerne les variables initialisées à partir des fichiers de configuration (.ini ou d'autres -- aussi depuis la registry sous Windows), j'utilise une classe singleton qui contient la configuration -- c-à-d que je lis le fichier une fois, et le maintient dans un std::set (ou un tableau haché). Normalement, l'interface du singleton ne donne pas d'accès en écriture aux éléments dans ce tableau ; pour le modifier, il faut appeler une fonction spécial avec le nom du fichier. Pour les INI, j'utilise la classe TIniFile (avec l'avantage d'avoir
une TRegistryIniFile, qui facilite le basculement d'un choix à l'autre).
Pierre
kanze@gabi-soft.fr typa:
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<jr6d80d3obj9eudc10gnvt56jhlaq8j52h@4ax.com>...
Il est fréquent que des variables (de tous types) soient initialisées
par la lecture d'un fichier INI par exemple, voire un calcul ou
l'appel d'une fonction en début de programme. Il peut arriver que ces
"constantes" soient modifiables "exceptionnellement" par un
utilisateur identifié (on peut alors se ramener au précédent, par
clôture/initialisation). Il me semble normal de conserver le statut
const à ces variables. Pour l'instant, j'utilise quelques cast, et ça
roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
Mais peu importe, voir ma réponse au post de Falk.
En ce qui concerne les variables initialisées à partir des fichiers de
configuration (.ini ou d'autres -- aussi depuis la registry sous
Windows), j'utilise une classe singleton qui contient la
configuration -- c-à-d que je lis le fichier une fois, et le maintient
dans un std::set (ou un tableau haché). Normalement, l'interface du
singleton ne donne pas d'accès en écriture aux éléments dans ce
tableau ; pour le modifier, il faut appeler une fonction spécial avec le
nom du fichier.
Pour les INI, j'utilise la classe TIniFile (avec l'avantage d'avoir
une TRegistryIniFile, qui facilite le basculement d'un choix à
l'autre).
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours. Je faisais parfois des trucs comme:
const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
En ce qui concerne les variables initialisées à partir des fichiers de configuration (.ini ou d'autres -- aussi depuis la registry sous Windows), j'utilise une classe singleton qui contient la configuration -- c-à-d que je lis le fichier une fois, et le maintient dans un std::set (ou un tableau haché). Normalement, l'interface du singleton ne donne pas d'accès en écriture aux éléments dans ce tableau ; pour le modifier, il faut appeler une fonction spécial avec le nom du fichier. Pour les INI, j'utilise la classe TIniFile (avec l'avantage d'avoir
une TRegistryIniFile, qui facilite le basculement d'un choix à l'autre).
Pierre
Falk Tannhäuser
Pierre Maurette wrote:
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
const int tt = 0; int main() { *const_cast<int*>(&tt) = 20; // ou simplement //const_cast<int&>(tt) = 21; return 0; }
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin sous Windows 2000) - le const_cast est là pour dire au compilo de la fermer ! Par contre, à l'exécution, ce programme m'affiche "Signal 11" (sous Linux: "Memory fault") sans qu'il y ait un std::cout ou printf dedans - magique non ?
À plus Falk
Pierre Maurette wrote:
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
const int tt = 0;
int main()
{
*const_cast<int*>(&tt) = 20;
// ou simplement
//const_cast<int&>(tt) = 21;
return 0;
}
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin
sous Windows 2000) - le const_cast est là pour dire au compilo
de la fermer !
Par contre, à l'exécution, ce programme m'affiche "Signal 11"
(sous Linux: "Memory fault") sans qu'il y ait un std::cout
ou printf dedans - magique non ?
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
const int tt = 0; int main() { *const_cast<int*>(&tt) = 20; // ou simplement //const_cast<int&>(tt) = 21; return 0; }
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin sous Windows 2000) - le const_cast est là pour dire au compilo de la fermer ! Par contre, à l'exécution, ce programme m'affiche "Signal 11" (sous Linux: "Memory fault") sans qu'il y ait un std::cout ou printf dedans - magique non ?
À plus Falk
Pierre Maurette
Falk Tannhäuser typa:
Pierre Maurette wrote:
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
const int tt = 0; int main() { *const_cast<int*>(&tt) = 20; // ou simplement //const_cast<int&>(tt) = 21; return 0; }
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin sous Windows 2000) - le const_cast est là pour dire au compilo de la fermer ! Par contre, à l'exécution, ce programme m'affiche "Signal 11" (sous Linux: "Memory fault") sans qu'il y ait un std::cout ou printf dedans - magique non ? 1 - Au temps pour moi, les seuls tests "réels" que j'ai fait sont en
C. Les casts à la C++ compilent, mais après, c'est la guerre. 2 - Justement, j'avais posté parce que les cast me gênaient. C'est une grosse bêtise, il y a uns solution dans chacun des langages à base de retour de pointeur (ou reference) const, ou de getters.
Ce qui se passe dans: *const_cast<int*>(&tt) = 20; ou int*ptt = const_cast<int*>(&tt); *ptt = 45; C'est qu'en castant à la barbare, on finit par initialiser une pointeur (non const), temporaire dans le premier cas, à l'adresse d'un const int. Si cette adresse est dans un segment read-only, on est de la baise. Exception ou même "rien" (semble être le cas sous XP).
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
const int tt = 0;
int main()
{
*const_cast<int*>(&tt) = 20;
// ou simplement
//const_cast<int&>(tt) = 21;
return 0;
}
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin
sous Windows 2000) - le const_cast est là pour dire au compilo
de la fermer !
Par contre, à l'exécution, ce programme m'affiche "Signal 11"
(sous Linux: "Memory fault") sans qu'il y ait un std::cout
ou printf dedans - magique non ?
1 - Au temps pour moi, les seuls tests "réels" que j'ai fait sont en
C. Les casts à la C++ compilent, mais après, c'est la guerre.
2 - Justement, j'avais posté parce que les cast me gênaient. C'est une
grosse bêtise, il y a uns solution dans chacun des langages à base de
retour de pointeur (ou reference) const, ou de getters.
Ce qui se passe dans:
*const_cast<int*>(&tt) = 20;
ou
int*ptt = const_cast<int*>(&tt);
*ptt = 45;
C'est qu'en castant à la barbare, on finit par initialiser une
pointeur (non const), temporaire dans le premier cas, à l'adresse d'un
const int. Si cette adresse est dans un segment read-only, on est de
la baise. Exception ou même "rien" (semble être le cas sous XP).
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
const int tt = 0; int main() { *const_cast<int*>(&tt) = 20; // ou simplement //const_cast<int&>(tt) = 21; return 0; }
chez moi, ça passe la compilation sans broncher (gcc 3.3.1 Cygwin sous Windows 2000) - le const_cast est là pour dire au compilo de la fermer ! Par contre, à l'exécution, ce programme m'affiche "Signal 11" (sous Linux: "Memory fault") sans qu'il y ait un std::cout ou printf dedans - magique non ? 1 - Au temps pour moi, les seuls tests "réels" que j'ai fait sont en
C. Les casts à la C++ compilent, mais après, c'est la guerre. 2 - Justement, j'avais posté parce que les cast me gênaient. C'est une grosse bêtise, il y a uns solution dans chacun des langages à base de retour de pointeur (ou reference) const, ou de getters.
Ce qui se passe dans: *const_cast<int*>(&tt) = 20; ou int*ptt = const_cast<int*>(&tt); *ptt = 45; C'est qu'en castant à la barbare, on finit par initialiser une pointeur (non const), temporaire dans le premier cas, à l'adresse d'un const int. Si cette adresse est dans un segment read-only, on est de la baise. Exception ou même "rien" (semble être le cas sous XP).
Pierre
Michel Michaud
Dans news:, Pierre
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ.
-- Michel Michaud http://www.gdzid.com FAQ de fr.comp.lang.c++ : http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
Dans news:q09f80d9lhfh2fcd4rmemmrl5qpm4rjpoh@4ax.com, Pierre
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un
const n'est correct (i.e. pas « undefined ») seulement
si on sait que l'objet n'est pas const au départ.
--
Michel Michaud mm@gdzid.com
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ.
-- Michel Michaud http://www.gdzid.com FAQ de fr.comp.lang.c++ : http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
Pierre Maurette
"Michel Michaud" typa:
Dans news:, Pierre
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ. Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123; const int* P = &Nom_a_la_con_pour_ecrire; #define Param (*P) // bla bla //Param = 5; // Refusé std::cout << Param << std::endl;
On est certain que la variable existe dans une zone RW.
Pierre
"Michel Michaud" <mm@gdzid.com> typa:
Dans news:q09f80d9lhfh2fcd4rmemmrl5qpm4rjpoh@4ax.com, Pierre
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un
const n'est correct (i.e. pas « undefined ») seulement
si on sait que l'objet n'est pas const au départ.
Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce
qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123;
const int* P = &Nom_a_la_con_pour_ecrire;
#define Param (*P)
// bla bla
//Param = 5; // Refusé
std::cout << Param << std::endl;
On est certain que la variable existe dans une zone RW.
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ. Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123; const int* P = &Nom_a_la_con_pour_ecrire; #define Param (*P) // bla bla //Param = 5; // Refusé std::cout << Param << std::endl;
On est certain que la variable existe dans une zone RW.
Pierre
kanze
Pierre Maurette wrote in message news:...
typa:
Pierre Maurette wrote in message news:...
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
Tout à fait. Et il existe bien des cas et des implémentations où ça ne marche pas -- ou bien, le compilateur voir que tt est const, et l'utilise directement la valeur d'initialisation, plutôt que de lire la variable, ou bien, le compilateur met la variable carrément dans un segment protégé en écriture, qui donne un core à l'affectation.
Note bien que c'est parce que l'objet même est const. Quelque chose du genre :
int maVar = 0 ; int const& v = maVar ;
*const_cast< int* >( &maVar ) = 20 ;
est parfaitement légal.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<q09f80d9lhfh2fcd4rmemmrl5qpm4rjpoh@4ax.com>...
kanze@gabi-soft.fr typa:
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<jr6d80d3obj9eudc10gnvt56jhlaq8j52h@4ax.com>...
Il est fréquent que des variables (de tous types) soient
initialisées par la lecture d'un fichier INI par exemple, voire un
calcul ou l'appel d'une fonction en début de programme. Il peut
arriver que ces "constantes" soient modifiables
"exceptionnellement" par un utilisateur identifié (on peut alors se
ramener au précédent, par clôture/initialisation). Il me semble
normal de conserver le statut const à ces variables. Pour
l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
Tout à fait. Et il existe bien des cas et des implémentations où ça ne
marche pas -- ou bien, le compilateur voir que tt est const, et
l'utilise directement la valeur d'initialisation, plutôt que de lire la
variable, ou bien, le compilateur met la variable carrément dans un
segment protégé en écriture, qui donne un core à l'affectation.
Note bien que c'est parce que l'objet même est const. Quelque chose du
genre :
int maVar = 0 ;
int const& v = maVar ;
*const_cast< int* >( &maVar ) = 20 ;
est parfaitement légal.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Il est fréquent que des variables (de tous types) soient initialisées par la lecture d'un fichier INI par exemple, voire un calcul ou l'appel d'une fonction en début de programme. Il peut arriver que ces "constantes" soient modifiables "exceptionnellement" par un utilisateur identifié (on peut alors se ramener au précédent, par clôture/initialisation). Il me semble normal de conserver le statut const à ces variables. Pour l'instant, j'utilise quelques cast, et ça roule.
Je suis curieux comment. Si j'écris :
extern int const i = 0 ;
et j'essaie plus tard à modifier la variable, au moyen de :
const_cast< int& >( i ) = 1 ;
j'ai un comportement indéfini, qui en fait ne marche pas toujours.
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-)
Tout à fait. Et il existe bien des cas et des implémentations où ça ne marche pas -- ou bien, le compilateur voir que tt est const, et l'utilise directement la valeur d'initialisation, plutôt que de lire la variable, ou bien, le compilateur met la variable carrément dans un segment protégé en écriture, qui donne un core à l'affectation.
Note bien que c'est parce que l'objet même est const. Quelque chose du genre :
int maVar = 0 ; int const& v = maVar ;
*const_cast< int* >( &maVar ) = 20 ;
est parfaitement légal.
-- James Kanze GABI Software mailto: Conseils en informatique orientée objet/ http://www.gabi-soft.fr Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jean-Marc Bourguet
Pierre Maurette writes:
"Michel Michaud" typa:
Dans news:, Pierre
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ. Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123; const int* P = &Nom_a_la_con_pour_ecrire; #define Param (*P) // bla bla //Param = 5; // Refusé std::cout << Param << std::endl;
Si tu veux jouer a ca, je prefere
int Nom_a_la_con_pour_ecrire = 123; int& Nom_a_la_con_pour_lire = Nom_a_la_con_pour_ecrire;
(Mais bon, il y a toujours le probleme de l'ordre d'initialisation des statiques).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Pierre Maurette <maurette.pierre@free.fr> writes:
"Michel Michaud" <mm@gdzid.com> typa:
Dans news:q09f80d9lhfh2fcd4rmemmrl5qpm4rjpoh@4ax.com, Pierre
Je faisais parfois des trucs comme:
const int tt = 0;
*const_cast<int*>(&tt) = 20;
*(int*)(&tt) = 21;
Ça passe sans avertir sur mes compilos.
Peut-être "par hasard" ? ;-)
Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un
const n'est correct (i.e. pas « undefined ») seulement
si on sait que l'objet n'est pas const au départ.
Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce
qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123;
const int* P = &Nom_a_la_con_pour_ecrire;
#define Param (*P)
// bla bla
//Param = 5; // Refusé
std::cout << Param << std::endl;
Si tu veux jouer a ca, je prefere
int Nom_a_la_con_pour_ecrire = 123;
int& Nom_a_la_con_pour_lire = Nom_a_la_con_pour_ecrire;
(Mais bon, il y a toujours le probleme de l'ordre d'initialisation des
statiques).
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Je faisais parfois des trucs comme: const int tt = 0; *const_cast<int*>(&tt) = 20; *(int*)(&tt) = 21; Ça passe sans avertir sur mes compilos. Peut-être "par hasard" ? ;-) Mais peu importe, voir ma réponse au post de Falk.
Pour être clair et précis : un const_cast qui enlève un const n'est correct (i.e. pas « undefined ») seulement si on sait que l'objet n'est pas const au départ. Voila...
Par exemple, celui-là est correct, je ne l'avais pas posté, parce qu'un peu gag:
int Nom_a_la_con_pour_ecrire = 123; const int* P = &Nom_a_la_con_pour_ecrire; #define Param (*P) // bla bla //Param = 5; // Refusé std::cout << Param << std::endl;
Si tu veux jouer a ca, je prefere
int Nom_a_la_con_pour_ecrire = 123; int& Nom_a_la_con_pour_lire = Nom_a_la_con_pour_ecrire;
(Mais bon, il y a toujours le probleme de l'ordre d'initialisation des statiques).
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org