Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting typeof to string

Tags:

c

gcc

typeof

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.

like image 815
user2868331 Avatar asked May 25 '15 12:05

user2868331


People also ask

How do you turn an object into a string?

We can convert Object to String in java using toString() method of Object class or String. valueOf(object) method. You can convert any object to String in java whether it is user-defined class, StringBuilder, StringBuffer or anything else.

How do you change a type to a string in TypeScript?

We convert any type to string by using String(x) or x. toString .

How do you turn something into a string in JavaScript?

Values can be explicitly converted to strings by calling either String() or n. toString() . With the String() function, let's convert a Boolean value to a string by passing the value true into the parameters for String() .


2 Answers

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;
like image 110
tmlen Avatar answered Oct 25 '22 04:10

tmlen


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).

like image 22
too honest for this site Avatar answered Oct 25 '22 05:10

too honest for this site