Comment puis-je vérifier si une variable est d'un certain type (comparer les deux types) en C?
En C (pas C++/C#) comment puis-je vérifier si une variable est d'un certain type?
Par exemple, quelque chose comme ceci:
double doubleVar;
if( typeof(doubleVar) == double ) {
printf("doubleVar is of type double!");
}
Ou plus générale: Comment comparer les deux types de sorte que compare(double1,double2)
sera évaluée à true, et compare(int,double)
sera false. Je tiens aussi à comparer les structures de composition différente ainsi.
En gros, j'ai une fonction qui fonctionne sur des variables de type "struct" et de "struct b". Je veux faire une chose avec la "struct un" variables et l'autre avec le "struct b" des variables. Depuis C ne supporte pas la surcharge et la void
pointeur de la perte des informations de type j'ai besoin de vérifier pour le type. BTW, quel serait le sens d'avoir un typeof
opérateur, si vous ne pouvez pas comparer les types?
La sizeof méthode semble être une solution de rechange pratique pour moi. Merci pour votre aide. Je trouve toujours ça un peu étrange, car les types sont connus au moment de la compilation, mais si j'imagine que le processus dans la machine, je peux voir, pourquoi l'information n'est pas stockée en termes de types, mais plutôt en termes de taille en octets. La taille est la seule chose vraiment pertinentes en plus des adresses.
- Ne pouvez-vous pas de vous jeter à un double (et ajouter
0.00
)? Vous ne savez pas si c'est possible en C, juste une suggestion. - Regarder dans le code source, il indique là que doubleVar est un double. Pas besoin(et pas possible non plus) pour le vérifier au moment de l'exécution.
- En réponse à Edit #1: avez-vous envisagé d'utiliser des pointeurs de fonction (comme une vtable) pour résoudre votre problème?
- Si vous aimez le sizeof methode, de lire cet article à propos de la tgmath mise en œuvre de la gcc.
- Foukarakis pourriez-vous fournir un exemple?
Vous devez vous connecter pour publier un commentaire.
Obtenir le type d'une variable est désormais possible en C11 avec le
_Generic
générique de sélection. Il fonctionne au moment de la compilation.La syntaxis est un peu comme
switch
. Voici un exemple (à partir de cette réponse):De l'utiliser pour la compilation du manuel de vérification de type, vous pouvez définir un
enum
avec tous les types que vous attendez, quelque chose comme ceci:Et ensuite utiliser
_Generic
pour les types de correspondance à ceenum
:C ne prend pas en charge cette forme de type de l'introspection. Ce que vous demandez n'est pas possible en C (au moins sans compilateur extensions spécifiques; il serait possible en C++, cependant).
En général, avec C vous êtes censés connaître le type de la variable. Étant donné que chaque fonction a types de béton pour ses paramètres (sauf pour les varargs, je suppose), vous n'avez pas besoin de vérifier dans le corps de la fonction. Le seul cas restant je peux voir, c'est dans une macro corps, et, eh bien, C macros ne sont pas vraiment tout ce que puissante.
De plus, notez que C ne conserve pas les informations de type à l'exécution. Cela signifie que, même si, hypothétiquement, il y avait un type de comparaison d'une extension, il ne fonctionne correctement que si les types sont connus au moment de la compilation (c'est à dire, que ça ne marcherait pas pour tester si deux
void *
point pour le même type de données).Comme pour
typeof
: tout d'Abord,typeof
est un GCC extension. Ce n'est pas une partie standard de C. Il est généralement utilisé pour écrire des macros que seulement évaluer leurs arguments une fois, par exemple, (à partir de la Manuel de GCC):La
typeof
mot-clé permet de la macro définir un local temporaire pour enregistrer les valeurs de ses arguments, leur permettant d'être évaluées qu'une seule fois.En bref, C ne prend pas en charge la surcharge; vous aurez juste à faire un
func_a(struct a *)
etfunc_b(struct b *)
, et d'appeler la bonne. Alternativement, vous pourriez faire votre propre introspection système:Vous devez, bien sûr, n'oubliez pas d'initialiser l'en-tête correctement lors de la création de ces objets.
struct a
branche, même si c'est unstruct b
. 🙂single
oudouble
. Comment puis-je le faire? Je sais qu'il peut être à une seule fonction. Mais puis-je créer un wrapper qui détermine le type et l'appeler le plus approprié? Je Vous Remercie.Que d'autres personnes ont déjà dit ce n'est pas pris en charge dans le langage C. Vous pouvez, toutefois, de vérifier la taille d'une variable à l'aide de la
sizeof()
fonction. Cela peut vous aider à déterminer si deux variables peut stocker le même type de données.Avant de le faire, lire les commentaires ci-dessous.
struct STATIC_ASSERT_size_not_equal_s { char STATIC_ASSERT_size_not_equal[sizeof(a) == sizeof(b) ? -1 : 1]; };
sizeof (int) == sizeof (float)
, mais ils ont complètement différent format de stockage.Comme d'autres l'ont mentionné, vous ne pouvez pas extraire le type d'une variable lors de l'exécution. Cependant, vous pouvez construire votre propre "objet" et de stocker le type avec elle. Alors vous seriez en mesure de le vérifier au moment de l'exécution:
Puis définissez le type de besoin dans le code:
Gnu GCC a un builtin fonction pour comparer les types de
__builtin_types_compatible_p
.https://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/Other-Builtins.html
Utilisé dans votre exemple:
C'est follement stupide, mais si vous utilisez le code:
et que vous utilisez le Mur du pavillon lors de la compilation, puis gcc sera le coup d'un avertissement de qui elle attend un argument de "unsigned int" alors que l'argument est de type '____'. (Si cet avertissement n'apparaît pas, alors la variable est de type "unsigned int".)
Bonne chance!
Edit: Que a grandi ci-dessous, cela s'applique uniquement au moment de la compilation. Très utile lorsque vous essayez de comprendre pourquoi votre pointeurs ne sont pas d'agir, mais pas très utile en cas de besoin lors de l'exécution.
De linux/typecheck.h:
Ici vous pouvez en trouver l'explication qui consolidés à partir de la norme et qui GNU extensions de code ci-dessus utilise.
(Peut-être un peu pas dans le champ d'application de la question, car la question n'est pas à propos de l'échec sur l'incompatibilité de type, mais de toute façon, en laissant ici).
Comme une autre réponse mentionné, vous pouvez désormais le faire en C11 avec
_Generic
.Par exemple, voici une macro qui permet de vérifier si une entrée est compatible avec un autre type:
Vous pouvez utiliser la macro comme ceci:
Cela peut aussi être utilisé sur d'autres types, y compris des structures. E. g.
Et sur les typedefs.
Cependant, il n'est pas toujours vous donner la réponse que vous attendez. Par exemple, il ne peut pas distinguer entre un tableau et un pointeur.
Réponse emprunté à partir d'ici: http://www.robertgamble.net/2012/01/c11-generic-selections.html
C est statiquement typé langue. Vous ne pouvez pas déclarer une fonction qui opèrent sur de type A ou de type B, et vous ne pouvez pas déclarer la variable qui détiennent de type A ou de type B. Chaque variable a explicitement déclaré et immuable type, et ce que vous êtes censé utiliser cette connaissance.
Et quand vous voulez savoir si void * points pour la mémoire de la représentation de flottant ou entier - que vous avez à stocker cette information quelque part d'autre. La langue est spécialement conçu pour ne pas les soins si char * points à quelque chose stockées en tant que int ou char.
À cette fin, j'ai écrit un simple programme en C pour ça...
C'est dans github...GitHub Lien
Voici comment cela fonctionne...
D'abord convertir votre double dans une chaîne de char nommé s..
Ensuite utiliser ma
dtype
fonction pour déterminer le type de...Ma fonction retourne un caractère unique...Vous pouvez l'utiliser comme ça...
Ensuite, vous pouvez utiliser la comparaison pour vérifier...
C'est ça...