Reputation: 1764
Usually when I need the type in C for something I don't know I'll just print it with a wrong format and see what gcc
tells me. For example:
int printme(int n, ...)
{
// What type is `va_list` ??
va_list ap;
printf("%d", ap);
}
int main(void)
{
printme("Hi", "There");
}
> a.c:12:14: warning: format ‘%d’ expects argument of type ‘int’,
but argument 2 has type ‘__va_list_tag *’ [-Wformat=]
printf("%d", ap);
Is there a better way to inspect the type of something for debugging purposes?
Upvotes: 0
Views: 179
Reputation: 12635
Type of va_list
is a compiler implementation defined type. Basically is a type necessary to be able to do the following, when used with these macros:
void f(int a, int b, double fmt, ...)
{
va_list p;
va_start(p, fmt); /* save the address in the stack of parameter `fmt` */
....
SOME_TYPE q = va_arg(p, SOME_TYPE);
....
SOME_TYPE q = va_arg(p, SOME_TYPE);
....
va_end(p);
}
which is how the thing is prepared to work.
Old implementations used a void *[1]
type (an array of one pointer to void element --- or even a char *[]
pointer, in very old implementations) to store there the reference to the first parameter, which was moved by the sizeof (SOME_TYPE)
when va_arg
macro was called (SOME_TYPE
is not restricted to be always the same type, you can change the type in each call to va_arg
). But today, it is normally implemented as some intrinsic function of the compiler, as some knowledge of how the stack is incremented/decremented or how the compiler handlers register passed parameters is necessary to implement it.
If you don't get so complex, and you have to know e.g. how the type dev_t
is defined (this is a posix type, not an ansi-c type, because it is the type that a posix type uses to represent a device in the kernel) and you need to print it, then you can always cast it to an int
(or a long
) and use that in your printf
format.
Historically there have been some approaches to this (like using z
modifier in the format string to print a size_t
or ssize_t
data type) but not every compiler has them implemented and this force you to stick on one of the last standards. If you want to produce portable code, the casting mechanism is probably the best, if you know a priori that the value is going to fit in the type you use to print.
Upvotes: 1
Reputation: 12590
Yes, there is a better way, and I'd say, it is the only Right Thing(TM) to do:
Read the source defining the data type.
Generally, C has no way to tell you during run time, what type a value has. Other languages have "reflection" or a similar feature, but not C.
To simplify this task, you might like to use a tool that reads all source files and header files of your project, and that gives you an overview. However, software recommendations are out of scope of this site.
Upvotes: 1