Comment vérifier si un pointeur, en C, est d'un certain type?
Comment voulez-vous vérifier si un pointeur est d'un certain type?
À l'aide de sizeof
n'est pas suffisant.
J'essaie d'éviter de mettre des numéros d'identification dans mes structures à identifier leur type. L'hypothèse est que peut-être gcc met en place une structure de définition de quelque part dans le processus, et les cartes de la définition de la mémoire allouée à un pointeur. Si c'est vrai, j'avais pensé qu'il y aurait d'une certaine manière à vérifier les pointeurs de type.
source d'informationauteur Crazy Chenz
Vous devez vous connecter pour publier un commentaire.
Gcc ne met pas la définition de la structure de n'importe où dans le runtime. Cela signifie que vous ne pouvez pas en standard.
Il peut dépendre de ce que vous êtes en utilisant les informations de type pour. Deux applications principales:
Dans le premier cas, l'information est souvent stockées dans les symboles de sortie par le compilateur et attaché à l'exécutable (dans de nombreux environnements).
La mise en œuvre de la plate-forme, ce qui implique souvent le compilateur doit être indiqué à la sortie de cette information. Un exemple de programme de le faire, c'est de gdb. Les pointeurs doivent encore être tapé correctement pour que cela soit utile.
Pour la sérialisation types sont souvent marqués avec des valeurs comme vous le suggérez. Ces balises ne pas bien être stockées avec les données en mémoire. Ils peuvent être ajoutés à la sortie de la routine.
Vous ne pouvez pas.
Un pointeur simplement stocke une adresse et de rien concernant le contenu de cette adresse.
"J'essaie d'éviter de mettre de la idnumbers dans mes structures à identifier leur type." Ne pas l'éviter. Si vous voulez vraiment être en mesure de vérifier le type de, mettre un typeID que le premier élément de chaque structure. Votre impulsion n'était pas une mauvaise.
Pointeur est le type. Plus généralement, C ne fournit pas la capacité de faire de l'introspection. Il n'y a pas programmatiques façon de déterminer le type d'une variable.
Toutes les réponses postées ici dire "vous ne pouvez pas." Ils sont de droite. Vous ne pouvez pas.
Mais, et j'hésite même à le mentionner, il y sont jeux qui peuvent être joués. Ces jeux sont un mauvaise idée. Je ne recommande pas non plus dans n'importe quelle situation.
Quel est le jeu? La farce steaky supplémentaire bits de données dans les parties non utilisées de l'adresse, et de les dépouiller de main chaque fois que vous utilisez l'adresse.
Imaginez que vous ayez des pointeurs vers une structure ou une classe de 32 octets la taille. Si vous assurez-vous que vos allocations de mémoire sont alignées par rapport à 32 octets de l'adresse, (ce qui est facile pour les allocations dynamiques mais plus délicat à garantie pour la pile), les bits de poids faibles de l'adresse seront tous 0. Cela signifie qu'il y a 5 gratuit bits à la partie inférieure de l'adresse, assez pour vous de mettre des drapeaux, des numéros d'identification, les valeurs d'état, etc. Le stockage est gratuit!
Même si vous avez une drôle de la taille de la structure, pratiquement toutes les C ou C++ compilateur et de l'OS sera toujours aligner toutes les adresses de 4 octets.
En 64 bits, vous pouvez généralement trouver un grand nombre de bits dans le haut de gamme des adresses... très probablement 16 gratuit les bits non utilisés, en attente pour vous. C'est l'OS dépendante de cours. Et aussi une mauvaise une mauvaise idée à envisager. Vous aimez le danger, n'est-ce pas?
Les deux inconvénients sont:
les valeurs avant de vous essayer à
déréférencer le pointeur ou de la transmettre
pour tout ce qui peut l'essayer. Cela rend
laide du code.
unportability falaise de stupide
les dangers. C'est comme boire une
bouteille de tequila et de la marche d'un effiloché de
sur la corde raide de plus de tigres affamés. Nude.
Votre sort si vous suivez mes conseils http://ecoworldly.com/files/2008/11/siberian-tiger-amur-tiger-korean-tiger.jpg
Il ya tellement de façons que cela va exploser en bugs, plantages, et de la douleur. Rappelez-vous comment je l'ai dit que les compilateurs aligner mémoire d'au moins 4 octets? Eh bien, c'est vrai. Jusqu'à ce que vous trouver un nouvel OS qui ne fonctionne pas. Et vous êtes tiger alimentaire.
Afin de ne pas le faire.
Mais, cela dit, c'est en effet un moyen pour les trucs un peu plus d'info, comme un numéro de type dans chaque adresse. Vous pouvez voir cette technique dans chaque octet-nombre de codeou Obfusicated C.
PS: Vraiment, je veux dire, ne pas le faire. Même si vous aimez les tigres.
Non, il n'y a pas de runtime type d'informations n'importe où.
Vous devriez écrire vos fonctions ainsi que la signature de la fonction porte le type de l'information et de permettre au compilateur de vérifier les types de manière statique. Par exemple
void burp_foo(struct foo *thefoo)
indique que l'argument est un pointeur vers unstruct foo
. C'est à l'appelant de fournir une. Bien sûr, grâce à la conversion de type, il est possible de fournir tout pointeur pointant vers unstruct foo
mais alors c'est de l'appelant problème, pas le vôtre.Vous ne pouvez pas le faire en C. en Fait le compilateur C++ fait quelque chose comme ce que vous voulez (le stockage des informations sur le type d'une classe à la mémoire allouée). En C, vous avez pas de classes, mais seulement les structures, qui ne contiennent pas de frais généraux que ce soit.
Un moyen d'éviter de mettre un ID membre dans votre structure est d'utiliser le polymorphisme comme :
Remarque vous pouvez augmenter
object_info_t
avec des pointeurs de fonction et d'éviter la vérification desid
s :Il n'y a rien de ce genre dans C. Un pointeur est un type spécifique ou c'est
void*
. Il n'y a pas de surcharge de fonctions ou intégré dans le polymorphisme d'exécution comme en C++. Vous pourrez faire de la pseudo orientée objet astuces en utilisant des pointeurs de fonction, comme:Le C standard ne permettent pas directement. La norme C++ a une capacité à faire (
dynamic_cast
ettypeid
).typeof
GCC est livré avec un opérateur typeof qui peut être utile en fonction de ce que vous faites.
opérateur conditionnel
L'opérateur conditionnel (le point d'interrogation et du côlon dans des expressions comme
x = y == 0 ? 1 : 0;
) a une certaine capacité à vous dire si les deux types peuvent être contraints à un troisième type (que l'article est sur le C++, mais le type de la sécurité de l'opérateur conditionnel est la même en C). Son utilisation est non évidentes pour dire le moins.Ces deux techniques (
typeof
et l'opérateur conditionnel) sont limités à l'information disponible au moment de la compilation. Qui est, vous ne pouvez pas passer unvoid*
à une fonction et l'utilisationtypeof
de comprendre le type d'origine de l'objet sur laquelle pointe le pointeur à l'intérieur de cette fonction (parce que de telles informations ne sont pas disponibles à l'intérieur de cette fonction au moment de la compilation).De penser plus à ce sujet, GTK+ est écrit en C et dispose d'un système vous pouvez envisager d'émulation. On dirait qu'ils le type d'utilisation IDs, mais au lieu de mettre l'Id dans la structure, ils utilisent des macros pour regarder les choses en place.
Bien l'une des voies possibles serait d'enregistrer l'adresse de pointeur et d'incrémenter le pointeur de voir la nouvelle adresse. La différence vous donner un indice.