OVH Cloud OVH Cloud

reinterpret_cast

16 réponses
Avatar
Vincent Richard
Bonjour,

Soit le programme suivant :

extern int f(int* x);

typedef int (*my_f)(const int* x);

int main()
{
const int x =3D 1234;

int r =3D ((my_f)(f))(&x);
}

A savoir :

* 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 !

Vincent

6 réponses

1 2
Avatar
kanze
drkm wrote:
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' ;


Ce serait pas plutôt :

char const c = 'a' ;
char * p1 ;
char const * * p2 = & p1 ;
* p2 = & c ;
* p1 = 'b' ;

?


Tout à fait.

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 ».


Tu n'es pas seul. Pendant la normalisation de C, la plupart des
grosses têtes ont vu exactement comme toi -- on augmente le
const, donc c'est bon. Et ce n'est que tout à la fin que
quelqu'un avait remarqué l'exemple ci-dessus. Du coup, le C a
ajouté une règle pour l'interdire. Règle qui en fait aller trop
loin, et que le C++ a relaxé un peu.

--
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



Avatar
drkm
writes:

[ interdiction cast char * * -> char const * * ]

Du coup, le C a
ajouté une règle pour l'interdire. Règle qui en fait aller trop
loin, et que le C++ a relaxé un peu.


Ah, je ne savais pas qu'il y avait une différence sur ce point entre
le C et le C++. Quelle est-elle ?

--drkm

Avatar
Jean-Marc Bourguet
drkm writes:

writes:

[ interdiction cast char * * -> char const * * ]

Du coup, le C a
ajouté une règle pour l'interdire. Règle qui en fait aller trop
loin, et que le C++ a relaxé un peu.


Ah, je ne savais pas qu'il y avait une différence sur ce point entre
le C et le C++. Quelle est-elle ?


En C on ne peut jamais ajouter const apres le premier niveau, en C++
la regle est plus complexe et permet certains cas surs (je n'ai pas
verifie si elle permettait tous les cas surs) comme

char * * -> char const * const *

qui n'est pas permis en C.

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


Avatar
drkm
Jean-Marc Bourguet writes:

drkm writes:

Ah, je ne savais pas qu'il y avait une différence sur ce point entre
le C et le C++. Quelle est-elle ?


En C on ne peut jamais ajouter const apres le premier niveau, en C++
la regle est plus complexe et permet certains cas surs (je n'ai pas
verifie si elle permettait tous les cas surs) comme

char * * -> char const * const *

qui n'est pas permis en C.


Ok. Du genre « si l'on ajoute const à un niveau, les niveaux
supplémentaires doivent chacun être constant, également » ?

--drkm


Avatar
Jean-Marc Bourguet
drkm writes:

Jean-Marc Bourguet writes:

drkm writes:

Ah, je ne savais pas qu'il y avait une différence sur ce point entre
le C et le C++. Quelle est-elle ?


En C on ne peut jamais ajouter const apres le premier niveau, en C++
la regle est plus complexe et permet certains cas surs (je n'ai pas
verifie si elle permettait tous les cas surs) comme

char * * -> char const * const *

qui n'est pas permis en C.


Ok. Du genre « si l'on ajoute const à un niveau, les niveaux
supplémentaires doivent chacun être constant, également » ?


Les règles tiennent aussi compte de volatile.
Pour pouvoir assigner un
T cv_{1,n} * cv_{1,n-1} * ... cv{1,1} * cv{1,0}
à un
T cv_{2,n} * cv_{2,n-1} * ... cv{2,1} * cv{2,0}
Il faut que
- pour tout j > 0 si const est dans cv_{1,j} alors const
doit être dans cv_{2,j} et de même pour volatile
- si cv_{1,j} et cv_{2,j} sont différents, alors const doit
être dans chaque cv_{2,k} pour 0 < k < j

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



Avatar
drkm
Jean-Marc Bourguet writes:

drkm writes:

Ok. Du genre « si l'on ajoute const à un niveau, les niveaux
supplémentaires doivent chacun être constant, également » ?


Les règles tiennent aussi compte de volatile.
Pour pouvoir assigner un
T cv_{1,n} * cv_{1,n-1} * ... cv{1,1} * cv{1,0}
à un
T cv_{2,n} * cv_{2,n-1} * ... cv{2,1} * cv{2,0}
Il faut que
- pour tout j > 0 si const est dans cv_{1,j} alors const
doit être dans cv_{2,j} et de même pour volatile
- si cv_{1,j} et cv_{2,j} sont différents, alors const doit
être dans chaque cv_{2,k} pour 0 < k < j


Limpide et rigoureux. Merci.

--drkm


1 2