void* , compilation, taille inconnue - C++ - Programmation
Marsh Posté le 01-02-2009 à 18:35:56
std::cout << *reinterpret_cast<std::string*>(p) << std::endl; |
Ou alors je n'ai pas compris la question.
Marsh Posté le 01-02-2009 à 18:58:27
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 :
|
Marsh Posté le 01-02-2009 à 19:00:20
(Edité suite au croisement des messages)
Ton premier code compile si on ajoute un
Code :
|
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)
Marsh Posté le 01-02-2009 à 19:09:28
mais aprés quand on essaye de déréférencé p , (*p), le compilo sors:
error C2100: indirection non conforme
Marsh Posté le 01-02-2009 à 19:09:54
en faite c'est préciement ça qui me pose problème le déréfencement d'un void*
Marsh Posté le 01-02-2009 à 19:15:34
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*?
Marsh Posté le 01-02-2009 à 19:17:51
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 :
|
Marsh Posté le 01-02-2009 à 19:35:47
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*:
|
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.
Marsh Posté le 01-02-2009 à 20:20:14
ok
Marsh Posté le 07-02-2009 à 21:54:42
std::string n'a pas de v-table il me semble. Peu de classe standards ont une v-table. std::exception, si, par exemple.
Marsh Posté le 07-02-2009 à 22:03:15
surtout que rien n'impose à un compilo d'ilplanter le polymorphisme avec unt ableau physique pour la vtable.
Marsh Posté le 07-02-2009 à 22:03:52
ReplyMarsh Posté le 07-02-2009 à 22:05:12
De tête non. Mais je suppose que certaines vielleries ne le font pas genr eborland ou turbo C++
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.
Marsh Posté le 07-02-2009 à 22:08:02
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.
Marsh Posté le 07-02-2009 à 22:13:00
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
Marsh Posté le 08-02-2009 à 09:58:29
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.
Marsh Posté le 08-02-2009 à 11:25:41
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 :
|
Ca devrait afficher, sur une machine 32-bits
4 8
Quelque soit le niveau d'optimisation.
Marsh Posté le 08-02-2009 à 12:13:23
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 :
|
en
Code :
|
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 |
Ca va vraisemblablement le faire. Mais j'ai pas confiance en l'avenir pour ça.
Marsh Posté le 08-02-2009 à 12:19:14
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 ?
Marsh Posté le 08-02-2009 à 12:35:36
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.
Marsh Posté le 08-02-2009 à 12:39:14
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...
Marsh Posté le 08-02-2009 à 12:43:57
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 ...
Marsh Posté le 08-02-2009 à 12:56:17
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.
Marsh Posté le 09-02-2009 à 22:02:36
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*:
|
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.
Marsh Posté le 01-02-2009 à 18:30:58
Hi,
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.