Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1605 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  void* , compilation, taille inconnue

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

void* , compilation, taille inconnue

n°1845856
frenchtouc​co
Posté le 01-02-2009 à 18:30:58  profilanswer
 

Hi,
 

Code :
  1. int main()
  2. {
  3. void * p;
  4. std::string s("tintin" );
  5. p=reinterpret_cast<void*>(&s);
  6. }


 
Que faut-il faire pour pouvoir pointer string avec p, sans que cela fasse une erreur de compilation ?
Merci.


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
mood
Publicité
Posté le 01-02-2009 à 18:30:58  profilanswer
 

n°1845859
Elmoricq
Modérateur
Posté le 01-02-2009 à 18:35:56  profilanswer
 

std::cout << *reinterpret_cast<std::string*>(p) << std::endl;


[:spamafote]

 

Ou alors je n'ai pas compris la question.


Message édité par Elmoricq le 01-02-2009 à 18:38:24
n°1845863
frenchtouc​co
Posté le 01-02-2009 à 18:58:27  profilanswer
 

mais sous visual 2008 express ça passe pas, le compilo me sort ça :
 
 error C2036: 'void *' : taille inconnue
 
avec ces 3 lignes de code :
 

Code :
  1. void * p;
  2. std::string s("tintin" );
  3. p=reinterpret_cast<string*>(&s);


Message édité par frenchtoucco le 01-02-2009 à 18:59:06

---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
n°1845864
Un Program​meur
Posté le 01-02-2009 à 19:00:20  profilanswer
 

(Edité suite au croisement des messages)
 
Ton premier code compile si on ajoute un

Code :
  1. #include <string>


 
Ton second code compile même sans reinterpret_cast<>
 
Est-ce que tu peux préciser ta question?
 
(J'ai pas VC++, mais donne quand même un code complet qui reproduit ton problème)


Message édité par Un Programmeur le 01-02-2009 à 19:03:22
n°1845869
frenchtouc​co
Posté le 01-02-2009 à 19:09:28  profilanswer
 

mais aprés quand on essaye de déréférencé p , (*p), le compilo sors:
 
error C2100: indirection non conforme


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
n°1845870
frenchtouc​co
Posté le 01-02-2009 à 19:09:54  profilanswer
 

en faite c'est préciement ça qui me pose problème le déréfencement d'un void*


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
n°1845876
Un Program​meur
Posté le 01-02-2009 à 19:15:34  profilanswer
 

frenchtoucco a écrit :

en faite c'est préciement ça qui me pose problème le déréfencement d'un void*


 
J'ai du mal à imaginer un contexte où déréférencer un void* a du sens.  Quel problème cherches-tu à résoudre qui t'incite à dérérérencer un void*?

n°1845878
frenchtouc​co
Posté le 01-02-2009 à 19:17:51  profilanswer
 

c'est plus un code qui sert d'exemple pour afficher la vtable d'une classe, et pour cela j'ai besoin de déférencé un void*:
 

Code :
  1. void print_vtable ( A *  pa )
  2. {
  3.  unsigned  * p = reinterpret_cast<unsigned*>(pa);
  4.  void   * vt = reinterpret_cast<void  * >(p[0]);
  5. ....
  6. vt[0]


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
n°1845883
Un Program​meur
Posté le 01-02-2009 à 19:35:47  profilanswer
 

frenchtoucco a écrit :

c'est plus un code qui sert d'exemple pour afficher la vtable d'une classe, et pour cela j'ai besoin de déférencé un void*:
 

Code :
  1. void print_vtable ( A *  pa )
  2. {
  3.  unsigned  * p = reinterpret_cast<unsigned*>(pa);
  4.  void   * vt = reinterpret_cast<void  * >(p[0]);
  5. ....
  6. vt[0]



 
Si tu veux afficher de la mémoire brute, il faut utiliser des unsigned char* plutôt que des void*.
 
En passant, il y a de bonnes chances pour que ce code ne marche pas (autrement dit que même dans les implémentations utilisant une vtable*, ça ne t'en donne pas toujours le contenu).
 
* Je n'en connais pas d'autres mais ce n'est pas obligatoire.

n°1845895
frenchtouc​co
Posté le 01-02-2009 à 20:20:14  profilanswer
 

ok


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
mood
Publicité
Posté le 01-02-2009 à 20:20:14  profilanswer
 

n°1848470
jesus_chri​st
votre nouveau dieu
Posté le 07-02-2009 à 21:54:42  profilanswer
 

std::string n'a pas de v-table il me semble. Peu de classe standards ont une v-table. std::exception, si, par exemple.

n°1848474
Joel F
Real men use unique_ptr
Posté le 07-02-2009 à 22:03:15  profilanswer
 

surtout que rien n'impose à un compilo d'ilplanter le polymorphisme avec unt ableau physique pour la vtable.

n°1848476
jesus_chri​st
votre nouveau dieu
Posté le 07-02-2009 à 22:03:52  profilanswer
 

t'en connais qui ne font pas comme ça, par curiosité ?

n°1848478
Joel F
Real men use unique_ptr
Posté le 07-02-2009 à 22:05:12  profilanswer
 

De tête non. Mais je suppose que certaines vielleries ne le font pas genr eborland ou turbo C++ :o
 
Plus serieusement, je ne sais vraiment pas masi j'aime pas trop beaucoup les hack de ce genre qui dependent d'un a priori sur le compilateur.

n°1848481
jesus_chri​st
votre nouveau dieu
Posté le 07-02-2009 à 22:08:02  profilanswer
 

Stroustrup documente les v-table dans son livre, et il parle si peu souvent implémentation, que quand il le fait ça a tendance à être un truc inévitable.
 
Lire les v-table est un bon moyen de savoir si on pointe vers un objet correctement construit. Accessoirement ça donne le type réel d'un objet, car les v-table servent d'apui à typeid. Mais je suis d'accord avec toi sur le fait que c'est pas portable du tout, c'est à reserver au debug sur un compilo spécifique.

n°1848484
Joel F
Real men use unique_ptr
Posté le 07-02-2009 à 22:13:00  profilanswer
 

ouaip.
 
Apres bon, un objet correctement construit, si t'as fait de belle classe avec une strong exception safety, c'est evident. Mais bon.
 
Quant à typeid [:vomi]

n°1848528
Un Program​meur
Posté le 08-02-2009 à 09:58:29  profilanswer
 

jesus_christ a écrit :

t'en connais qui ne font pas comme ça, par curiosité ?


 
Pour d'autres langages que le C++, oui.
 
Dans un contexte de C++ traditionnel -- avec un éditeur de liens qui ne fait presque rien -- c'est difficile de faire foncièrement différemment.  Mais avec la montée des optimisations à l'édition de liens, il me semble probable que certains poussent plus loin la seule optimisation qui est parfois faite -- bypasser la vtable quand on connait le type statique.

n°1848542
jesus_chri​st
votre nouveau dieu
Posté le 08-02-2009 à 11:25:41  profilanswer
 

oui, mais l'optimization à la liaison, ou même simplement à la compile, permet de transformer un appel virtuel en appel static quand le type est connu (ce qui est rarement le cas quand on utilise le polymorphisme, justement) mais ça ne permet pas au compilo de jetter la v--table, qui est de toute façon incluse parmis les membre de la classe, en en modifiant la taille, et l'optimisation n'a pas le droit de changer la taille des types.
 

Code :
  1. struct A
  2. {
  3.     int n;
  4. };
  5. struct B
  6. {
  7.     virtual ~B() {} // pour avoir une vtable
  8.     int n;
  9. };
  10. int main()
  11. {
  12.     A a;
  13.     B b; // vtable inutile
  14.     std::cout << sizeof a << ' ' << sizeof b << '\n';
  15. }


 
Ca devrait afficher, sur une machine 32-bits
4 8
Quelque soit le niveau d'optimisation.

n°1848553
Un Program​meur
Posté le 08-02-2009 à 12:13:23  profilanswer
 

jesus_christ a écrit :

oui, mais l'optimization à la liaison, ou même simplement à la compile, permet de transformer un appel virtuel en appel static quand le type est connu (ce qui est rarement le cas quand on utilise le polymorphisme, justement)

 

Je n'ai jamais dit le contraire.  Mais si par hasard entre dans spec un programme qui va en profiter, je te garanti que dans les deux ans qui suivent il y aura des compilateurs pour faire cette optimisation.  Voir celui de Sun qui s'est mis à transformer

 
Code :
  1. struct s {
  2.    int x;
  3.    int y;
  4. } table[UN_GRAND_NOMBRE];
 

en

 
Code :
  1. int x[UN_GRAND_NOMBRE];
  2. int y[UN_GRAND_NOMBRE];
 
Citation :

mais ça ne permet pas au compilo de jetter la v--table, qui est de toute façon incluse parmis les membre de la classe, en en modifiant la taille, et l'optimisation n'a pas le droit de changer la taille des types.

 

D'après moi, un programme conforme ne peut pas dépendre de la différence.

 
Citation :

Ca devrait afficher, sur une machine 32-bits
4 8
Quelque soit le niveau d'optimisation.

 

Ca va vraisemblablement le faire.  Mais j'ai pas confiance en l'avenir pour ça.


Message édité par Un Programmeur le 08-02-2009 à 12:13:43
n°1848557
jesus_chri​st
votre nouveau dieu
Posté le 08-02-2009 à 12:19:14  profilanswer
 

Sun transforme les array-of-structure en structure-of-array ?
Ok c'est un peut mieux pour les perfs, mais j'ai un doute sur la validité du code derrière.
 
Si on fait
s* p = &table[42];
il fait comment le compilo ? p ne pointe plus vers un struct s ?

n°1848562
Joel F
Real men use unique_ptr
Posté le 08-02-2009 à 12:35:36  profilanswer
 

je suppose qu'il doit inferer les types afin de pas SoAifier n'importe comment. De la meme manière que les vectorisateurs automatiques s'arretent vite des que tu fais des trucs chelou sur tes valeurs.

n°1848564
jesus_chri​st
votre nouveau dieu
Posté le 08-02-2009 à 12:39:14  profilanswer
 

oui ça doit être ça, mais dès que le type est exposé à l'extérieur, genre vers un DLL/.so dont il ne connait pas le code, il doit s'arréter aussi. En gros ça marche pour une utilisation restreinte et dans des unités de compilation bien isolées. Pourquoi pas...

n°1848566
Joel F
Real men use unique_ptr
Posté le 08-02-2009 à 12:43:57  profilanswer
 

bah ca sert parait il. Je trouve ca limité et nevalant pas le label "vectorisateur automatique" amis tout le monde de la compil se paluche la dessus alors qu'arreter de faire de l'optimsiation aprés la RI au lieu de avant me parait mieux ...

n°1848570
Un Program​meur
Posté le 08-02-2009 à 12:56:17  profilanswer
 

jesus_christ a écrit :

oui ça doit être ça, mais dès que le type est exposé à l'extérieur, genre vers un DLL/.so dont il ne connait pas le code, il doit s'arréter aussi. En gros ça marche pour une utilisation restreinte et dans des unités de compilation bien isolées. Pourquoi pas...


 
Je l'ai dit, c'est le genre de choses qui sont faites pour gagner quelques points sur SPEC... (j'ai déjà entendu des rumeurs comme quoi certains compilateurs étaient tellement bien ajustés à SPEC que changer le nom de variable désactivait des optimisations)  Les conditions de validité sont tellement restreintes que ça me semble aussi du temps perdu que d'implémenter cela.  Mais je ne suis pas un grand utilisateur de calcul numérique, si ça tombe ma vision des choses est biaisée.

n°1849157
youen
Posté le 09-02-2009 à 22:02:36  profilanswer
 

frenchtoucco a écrit :

c'est plus un code qui sert d'exemple pour afficher la vtable d'une classe, et pour cela j'ai besoin de déférencé un void*:
 

Code :
  1. void print_vtable ( A *  pa )
  2. {
  3.  unsigned  * p = reinterpret_cast<unsigned*>(pa);
  4.  void   * vt = reinterpret_cast<void  * >(p[0]);
  5. ....
  6. vt[0]



 
Pour préciser un peu le problème, tu ne peux pas écrire vt[0], parce que le résultat aurait le type "void", ce qui n'a aucun sens. Par exemple si tu écrivais vt[1], il devrait aller chercher où ? à l'adresse de vt + 1 ? ou vt + 4 ? il ne connait pas la taille de chaque élément du tableau que tu veux lire, donc il ne peut rien faire.
 
Et d'ailleurs en écrivant vt[0], tu veux en faire quoi ? l'affecter à une variable ?
 
tu pourrais par exemple écrire int a = ((int*)vt)[0] mais comme d'autres l'ont dit, tu peux tomber sur un peu n'importe quoi avec ton code, selon le compilateur etc.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  void* , compilation, taille inconnue

 

Sujets relatifs
[ACCESS] Erreur de compilation requete VBAtaille page web
Taille du texte et affichage dans navigateur...[Py2exe] Problème de compilation
Modification de la taille d'un champ sous Oracle(réglé)afficher une grande image en vraie taille automatiquement
Adapter menu à la taille de la police du joueurCompilation MySQL avec C++ Builder 2006 [Resolu]
Probleme de compilation avec les templateProblème de compilation avec kwrite
Plus de sujets relatifs à : void* , compilation, taille inconnue


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR