Reputation: 333
Is there a way to convert gcc's typeof
extension to a string, for example:
#define printType(a) printf("%s", #typeof(a))
So that I can do:
int a = 4;
printf("Type of a is: ");
printType(a);
And get the output of:
Type of a is: int
A possible use of this would be as follows:
#include <stdio.h>
#define indirect_print(a) print_##typeof(a)(a)
void print_int(int *i) {
printf("%d", *i);
}
void print_char(char *c) {
printf("%c", *c);
}
int main(void) {
char C = 'C';
int I = 100;
{
char *a = &C;
indirect_print(a);
}
{
int *a = &I;
indirect_print(a);
}
return 0;
}
If possible, it should work for all types including structures and unions, without relying on adding every type to a list manually.
Upvotes: 17
Views: 3717
Reputation: 12263
The preprocessor runs before the compiler. So all its replacements are performed before the actual compilation is started. typeof()
is evaluated by the compiler, which would only see a string "typeof()"
which will obviously not be evaluated.
So, the answer is: not for pre-C11. For C11, see the answer of @tmlen, but be aware there are some ambiguities about the _Generic
type selectors which are resolved differently in different compilers, wich can result in problems with qualified types. There is a defect report about this issue, read Jens Gustedt's blob for details: https://gustedt.wordpress.com/2015/05/11/the-controlling-expression-of-_generic/#more-2256 (he also filed a defect report http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_423.htm).
Upvotes: 6
Reputation: 9090
Since C11, you can use a generic, see http://en.cppreference.com/w/c/language/generic. For example:
#define printType(a) printf("%s", _Generic( (a) , \
int : "int", \
long : "long", \
float : "float", \
default : "other type"))(a)
Every type that can be used needs to be listed.
In C++, there is also the typeid
keyword:
#include <typeinfo>
#define printType(a) std::cout << typeid(a).name() << std::endl;
Upvotes: 18