* il m'est impossible de modifier la d=E9claration de la fonction f()
* cette derni=E8re ne modifie pas son param=E8tre
* je ne veux pas "caster" le param=E8tre effectif "x"
Je cherche =E0 obtenir le m=EAme comportement avec un cast "=E0 la C++".
Un static_cast<> ne suffisant pas, je m'oriente vers ceci :
int r =3D (reinterpret_cast <my_f>(f))(&x);
Le comportement est-il le m=EAme ? Est-ce garanti de fonctionner sur
n'importe quel compilateur et/ou machine ?
(pour le pourquoi de cette question : j'utilise en fait une biblioth=E8que
externe dans laquelle f est parfois d=E9finie comme je l'ai indiqu=E9e, et
sur d'autres syst=E8mes avec le param=E8tre en 'const'. Je souhaite avoir
un code identique dans tous les cas.)
Merci d'avance pour vos r=E9ponses, et bonne ann=E9e !
Je cherche à obtenir le même comportement avec un cast "à la C++". Un static_cast<> ne suffisant pas, je m'oriente vers ceci :
int r = (reinterpret_cast <my_f>(f))(&x);
Le comportement est-il le même ?
Il me semble que la sémantique de reinterpret_cast<> est celle du cast à la C lorsque static_cast<> et const_cast<> ne sont pas d'application.
Heu, je ne sais pas si j'ai été clair, là. L'ensemble des conversions permises par static_cast<>, plus celui de const_cast<>, plus celui de reinterpret_cast<> == l'ensemble des conversions de l'opérateur de conversion à la C. Comme les deux premiers ne s'appliquent pas dans ce cas, je dirais qu'il s'agit bien de la même conversion.
Quant à la légalité et aux garanties de cette conversion (et surtout de l'appel qui est fait sur son résultat), je ne sais pas.
--drkm
Vincent Richard <chere-loque@plop.wanadoo.fr.invalid> writes:
Je cherche à obtenir le même comportement avec un cast "à la C++".
Un static_cast<> ne suffisant pas, je m'oriente vers ceci :
int r = (reinterpret_cast <my_f>(f))(&x);
Le comportement est-il le même ?
Il me semble que la sémantique de reinterpret_cast<> est celle du
cast à la C lorsque static_cast<> et const_cast<> ne sont pas
d'application.
Heu, je ne sais pas si j'ai été clair, là. L'ensemble des
conversions permises par static_cast<>, plus celui de const_cast<>,
plus celui de reinterpret_cast<> == l'ensemble des conversions de
l'opérateur de conversion à la C. Comme les deux premiers ne
s'appliquent pas dans ce cas, je dirais qu'il s'agit bien de la même
conversion.
Quant à la légalité et aux garanties de cette conversion (et surtout
de l'appel qui est fait sur son résultat), je ne sais pas.
Je cherche à obtenir le même comportement avec un cast "à la C++". Un static_cast<> ne suffisant pas, je m'oriente vers ceci :
int r = (reinterpret_cast <my_f>(f))(&x);
Le comportement est-il le même ?
Il me semble que la sémantique de reinterpret_cast<> est celle du cast à la C lorsque static_cast<> et const_cast<> ne sont pas d'application.
Heu, je ne sais pas si j'ai été clair, là. L'ensemble des conversions permises par static_cast<>, plus celui de const_cast<>, plus celui de reinterpret_cast<> == l'ensemble des conversions de l'opérateur de conversion à la C. Comme les deux premiers ne s'appliquent pas dans ce cas, je dirais qu'il s'agit bien de la même conversion.
Quant à la légalité et aux garanties de cette conversion (et surtout de l'appel qui est fait sur son résultat), je ne sais pas.
--drkm
Gabriel Dos Reis
Vincent Richard writes:
| Bonjour, | | Soit le programme suivant : | | extern int f(int* x); | | typedef int (*my_f)(const int* x); | | int main() | { | const int x = 1234; | | int r = ((my_f)(f))(&x); | } | | A savoir : | | * il m'est impossible de modifier la déclaration de la fonction f() | * cette dernière ne modifie pas son paramètre | * je ne veux pas "caster" le paramètre effectif "x" | | Je cherche à obtenir le même comportement avec un cast "à la C++". | Un static_cast<> ne suffisant pas, je m'oriente vers ceci : | | int r = (reinterpret_cast <my_f>(f))(&x); | | Le comportement est-il le même ? Est-ce garanti de fonctionner sur | n'importe quel compilateur et/ou machine ?
Chaque fois que tu utilises reinterpret_cast<> il faut regarder la doc du compilo.
Cependant, de manière générale, un static_cast<> ou un reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat est un rvalue). Cela veut dire que dans le cas présent, il faudrait que la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une fonction. Laquelle ?
| (pour le pourquoi de cette question : j'utilise en fait une bibliothèque | externe dans laquelle f est parfois définie comme je l'ai indiquée, et | sur d'autres systèmes avec le paramètre en 'const'. Je souhaite avoir | un code identique dans tous les cas.)
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) { #ifdef F_TAKES_CONST_ARG f (x); #else f ((int*) x); #endif }
| | Merci d'avance pour vos réponses, et bonne année ! | | Vincent
-- Gabriel Dos Reis
Vincent Richard <chere-loque@plop.wanadoo.fr.invalid> writes:
| Bonjour,
|
| Soit le programme suivant :
|
| extern int f(int* x);
|
| typedef int (*my_f)(const int* x);
|
| int main()
| {
| const int x = 1234;
|
| int r = ((my_f)(f))(&x);
| }
|
| A savoir :
|
| * il m'est impossible de modifier la déclaration de la fonction f()
| * cette dernière ne modifie pas son paramètre
| * je ne veux pas "caster" le paramètre effectif "x"
|
| Je cherche à obtenir le même comportement avec un cast "à la C++".
| Un static_cast<> ne suffisant pas, je m'oriente vers ceci :
|
| int r = (reinterpret_cast <my_f>(f))(&x);
|
| Le comportement est-il le même ? Est-ce garanti de fonctionner sur
| n'importe quel compilateur et/ou machine ?
Chaque fois que tu utilises reinterpret_cast<> il faut regarder la
doc du compilo.
Cependant, de manière générale, un static_cast<> ou un
reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat
est un rvalue). Cela veut dire que dans le cas présent, il faudrait que
la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une
fonction. Laquelle ?
| (pour le pourquoi de cette question : j'utilise en fait une bibliothèque
| externe dans laquelle f est parfois définie comme je l'ai indiquée, et
| sur d'autres systèmes avec le paramètre en 'const'. Je souhaite avoir
| un code identique dans tous les cas.)
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) {
#ifdef F_TAKES_CONST_ARG
f (x);
#else
f ((int*) x);
#endif
}
|
| Merci d'avance pour vos réponses, et bonne année !
|
| Vincent
| Bonjour, | | Soit le programme suivant : | | extern int f(int* x); | | typedef int (*my_f)(const int* x); | | int main() | { | const int x = 1234; | | int r = ((my_f)(f))(&x); | } | | A savoir : | | * il m'est impossible de modifier la déclaration de la fonction f() | * cette dernière ne modifie pas son paramètre | * je ne veux pas "caster" le paramètre effectif "x" | | Je cherche à obtenir le même comportement avec un cast "à la C++". | Un static_cast<> ne suffisant pas, je m'oriente vers ceci : | | int r = (reinterpret_cast <my_f>(f))(&x); | | Le comportement est-il le même ? Est-ce garanti de fonctionner sur | n'importe quel compilateur et/ou machine ?
Chaque fois que tu utilises reinterpret_cast<> il faut regarder la doc du compilo.
Cependant, de manière générale, un static_cast<> ou un reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat est un rvalue). Cela veut dire que dans le cas présent, il faudrait que la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une fonction. Laquelle ?
| (pour le pourquoi de cette question : j'utilise en fait une bibliothèque | externe dans laquelle f est parfois définie comme je l'ai indiquée, et | sur d'autres systèmes avec le paramètre en 'const'. Je souhaite avoir | un code identique dans tous les cas.)
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) { #ifdef F_TAKES_CONST_ARG f (x); #else f ((int*) x); #endif }
| | Merci d'avance pour vos réponses, et bonne année ! | | Vincent
-- Gabriel Dos Reis
Vincent Richard
Cependant, de manière générale, un static_cast<> ou un reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat est un rvalue). Cela veut dire que dans le cas présent, il faudrait que la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une fonction. Laquelle ?
Merci pour la réponse. Donc, il ne vaudrait mieux pas que j'utilise ça...
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) { #ifdef F_TAKES_CONST_ARG f (x); #else f ((int*) x); #endif }
La fonction en question est la fonction iconv(), déclarée de la maniè re suivante sur mon système (Debian GNU/Linux) :
et sur d'autres système avec le deuxième argument de type 'const char**' (qui est d'ailleurs, je crois, la définition "officielle" POSIX).
Je crois me souvenir qu'il existe des macros M4 utilisable avec 'autoconf' pour détecter si c'est l'un ou l'autre des 2 prototypes qui est utilisé, malheureusement, je n'utilise pas les autotools...
Cela dit, je ne crois pas que ça soit mieux que le reinterpret_cast<>. De plus, j'étais en train de remplacer tous les casts à la C par des casts à la C++ dans mon projet (lisibilité, etc.)...
Merci d'avance.
Vincent
Cependant, de manière générale, un static_cast<> ou un
reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat
est un rvalue). Cela veut dire que dans le cas présent, il faudrait que
la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une
fonction. Laquelle ?
Merci pour la réponse.
Donc, il ne vaudrait mieux pas que j'utilise ça...
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) {
#ifdef F_TAKES_CONST_ARG
f (x);
#else
f ((int*) x);
#endif
}
La fonction en question est la fonction iconv(), déclarée de la maniè re
suivante sur mon système (Debian GNU/Linux) :
et sur d'autres système avec le deuxième argument de type 'const char**'
(qui est d'ailleurs, je crois, la définition "officielle" POSIX).
Je crois me souvenir qu'il existe des macros M4 utilisable avec 'autoconf'
pour détecter si c'est l'un ou l'autre des 2 prototypes qui est utilisé,
malheureusement, je n'utilise pas les autotools...
Cela dit, je ne crois pas que ça soit mieux que le reinterpret_cast<>.
De plus, j'étais en train de remplacer tous les casts à la C par des
casts à la C++ dans mon projet (lisibilité, etc.)...
Cependant, de manière générale, un static_cast<> ou un reinterpret_cast<> construit une nouvelle valeur (lorsque le résultat est un rvalue). Cela veut dire que dans le cas présent, il faudrait que la valeur de reinterpret_cast <my_f>(f) corresponde à l'adresse d'une fonction. Laquelle ?
Merci pour la réponse. Donc, il ne vaudrait mieux pas que j'utilise ça...
T'est-il possible d'enrober l'appel à f() ? Genre :
static inline int my_f(const int* x) { #ifdef F_TAKES_CONST_ARG f (x); #else f ((int*) x); #endif }
La fonction en question est la fonction iconv(), déclarée de la maniè re suivante sur mon système (Debian GNU/Linux) :
et sur d'autres système avec le deuxième argument de type 'const char**' (qui est d'ailleurs, je crois, la définition "officielle" POSIX).
Je crois me souvenir qu'il existe des macros M4 utilisable avec 'autoconf' pour détecter si c'est l'un ou l'autre des 2 prototypes qui est utilisé, malheureusement, je n'utilise pas les autotools...
Cela dit, je ne crois pas que ça soit mieux que le reinterpret_cast<>. De plus, j'étais en train de remplacer tous les casts à la C par des casts à la C++ dans mon projet (lisibilité, etc.)...
Merci d'avance.
Vincent
Vincent Richard
J'ai finalement trouvé une solution, pas très propre certes, mais qui semble fonctionner :
Oui, c'est dual à la solution qui consiste à enrober la fonction. Il faudra juste faire attention aux « const » et « * » :
char* p = strcat(...); iconv(d, IconvHack(p), ...); ^^^
iconv( d , IconvHack( & p ) , ... ) ;
Je ne comprend pas ton « Il faudra juste faire attention aux "const" et "*" ». À quoi penses-tu en particulier ?
Il faut également être certain que `iconv()' ne modifie en aucun cas les objets pointés, non ?
--drkm
Gabriel Dos Reis
drkm writes:
| Gabriel Dos Reis writes: | | > Oui, c'est dual à la solution qui consiste à enrober la fonction. | > Il faudra juste faire attention aux « const » et « * » : | | > char* p = strcat(...); | > iconv(d, IconvHack(p), ...); | ^^^ | | iconv( d , IconvHack( & p ) , ... ) ;
Merci !
| Je ne comprend pas ton « Il faudra juste faire attention aux "const" | et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
-- Gaby
drkm <usenet.fclcxx@fgeorges.org> writes:
| Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
|
| > Oui, c'est dual à la solution qui consiste à enrober la fonction.
| > Il faudra juste faire attention aux « const » et « * » :
|
| > char* p = strcat(...);
| > iconv(d, IconvHack(p), ...);
| ^^^
|
| iconv( d , IconvHack( & p ) , ... ) ;
Merci !
| Je ne comprend pas ton « Il faudra juste faire attention aux "const"
| et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion
implicite de « T** » vers « const T** ».
Au delà d'un « * », les « const » c'est l'emmerdement maximal.
| Gabriel Dos Reis writes: | | > Oui, c'est dual à la solution qui consiste à enrober la fonction. | > Il faudra juste faire attention aux « const » et « * » : | | > char* p = strcat(...); | > iconv(d, IconvHack(p), ...); | ^^^ | | iconv( d , IconvHack( & p ) , ... ) ;
Merci !
| Je ne comprend pas ton « Il faudra juste faire attention aux "const" | et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
-- Gaby
drkm
Gabriel Dos Reis writes:
drkm writes:
| Je ne comprend pas ton « Il faudra juste faire attention aux "const" | et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
--drkm
Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
drkm <usenet.fclcxx@fgeorges.org> writes:
| Je ne comprend pas ton « Il faudra juste faire attention aux "const"
| et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion
implicite de « T** » vers « const T** ».
Au delà d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle
qui me surprend. « Ben quoi, j'augmente la contrainte de constance,
quel est le problème ? Ha, oui ... »
| Je ne comprend pas ton « Il faudra juste faire attention aux "const" | et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
--drkm
kanze
drkm wrote:
Gabriel Dos Reis writes:
drkm writes:
| Je ne comprend pas ton « Il faudra juste faire attention | aux "const" et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ; char ** p1 ; char const ** p2 = &p1 ; // C'est le char** -> char const** // qui est en fait illégal. *p2 = &c ; **p1 = 'b' ;
On n'aime pas pouvoir modifier un const sans qu'il y ait un const_cast quelque part.
-- James Kanze GABI Software http://www.gabi-soft.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
drkm wrote:
Gabriel Dos Reis <gdr@integrable-solutions.net> writes:
drkm <usenet.fclcxx@fgeorges.org> writes:
| Je ne comprend pas ton « Il faudra juste faire attention
| aux "const" et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de
conversion implicite de « T** » vers « const T** ». Au delà
d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est
une règle qui me surprend. « Ben quoi, j'augmente la
contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ;
char ** p1 ;
char const ** p2 = &p1 ; // C'est le char** -> char const**
// qui est en fait illégal.
*p2 = &c ;
**p1 = 'b' ;
On n'aime pas pouvoir modifier un const sans qu'il y ait un
const_cast quelque part.
--
James Kanze GABI Software http://www.gabi-soft.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
| Je ne comprend pas ton « Il faudra juste faire attention | aux "const" et "*" ». À quoi penses-tu en particulier ?
Le code ci-dessus ne compilera pas parce qu'il n'y a pas de conversion implicite de « T** » vers « const T** ». Au delà d'un « * », les « const » c'est l'emmerdement maximal.
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ; char ** p1 ; char const ** p2 = &p1 ; // C'est le char** -> char const** // qui est en fait illégal. *p2 = &c ; **p1 = 'b' ;
On n'aime pas pouvoir modifier un const sans qu'il y ait un const_cast quelque part.
-- James Kanze GABI Software http://www.gabi-soft.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
drkm
writes:
drkm wrote:
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ; char ** p1 ; ^^
char const ** p2 = &p1 ; // C'est le char** -> char const** ^^^
// qui est en fait illégal. *p2 = &c ; **p1 = 'b' ;
Mais ce que je voulais dire, c'est que je me surprends encore à avoir la première réaction de « Ben j'augmente la contrainte de constance, puisqu'il y a un 'const' en plus ». Avant le « Ha oui, dans '* p2 = & c ;', l'opérande effective de gauche est en fait de type 'char *' et celui de droite 'char const *' ».
--drkm
kanze@gabi-soft.fr writes:
drkm wrote:
Ok, je n'avais pas fait le lien. Encore maintenant, c'est
une règle qui me surprend. « Ben quoi, j'augmente la
contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ;
char ** p1 ;
^^
char const ** p2 = &p1 ; // C'est le char** -> char const**
^^^
// qui est en fait illégal.
*p2 = &c ;
**p1 = 'b' ;
Mais ce que je voulais dire, c'est que je me surprends encore à
avoir la première réaction de « Ben j'augmente la contrainte de
constance, puisqu'il y a un 'const' en plus ». Avant le « Ha oui,
dans '* p2 = & c ;', l'opérande effective de gauche est en fait de
type 'char *' et celui de droite 'char const *' ».
Ok, je n'avais pas fait le lien. Encore maintenant, c'est une règle qui me surprend. « Ben quoi, j'augmente la contrainte de constance, quel est le problème ? Ha, oui ... »
char const c = 'a' ; char ** p1 ; ^^
char const ** p2 = &p1 ; // C'est le char** -> char const** ^^^
// qui est en fait illégal. *p2 = &c ; **p1 = 'b' ;
Mais ce que je voulais dire, c'est que je me surprends encore à avoir la première réaction de « Ben j'augmente la contrainte de constance, puisqu'il y a un 'const' en plus ». Avant le « Ha oui, dans '* p2 = & c ;', l'opérande effective de gauche est en fait de type 'char *' et celui de droite 'char const *' ».