__builtin_va_list different on targets

Hi all,

I know __builtin_va_list is target-specific, and
ARM has typedef void* __builtin_va_list;
X86 has typedef char* __builtin_va_list;

It seems they can be treated as the same prototype,i.e… void*, at the header level.
What I want to ask is:

If I write a program use “typedef void* __builtin_va_list” on X86, and run it.
Would I face any problem on run-time?

I think it won’t make any trouble. But I’m not very sure.
Should anyone have similar experience?

Thanks a lot.

C guarantees that void* and char* have compatible representations, so
as long that’s the only difference, you won’t have runtime problems.
You can obviously have compile-time problems, though: for example,
in C, if va_list is a void*, then it can be implicitly converted to any pointer
type instead of (as with char*) only explicitly converted; and in C++, you
can get different manglings, which is actually how we found out that our
ARM target was misdeclaring it. But otherwise it should be fine, as long
as that’s the only difference.

However, other targets may have more complicated differences than
just void* vs. char*.


Thanks for your answer very much.

I wonder for what reason does ARM use void * but X86 use char * ?
Seems ARM uses void * since its spec said that.
But X86? I cannot find any reason or spec to specify why X86 uses char *, not void * directly?

Could anyone give me some hints?
Thanks a lot.

2011/5/23 John McCall <rjmccall@apple.com>

It’s just what GCC specifies. void* was introduced by C89, and GCC
predates that, so it’s likely that it’s still char* for really, really historical
reasons. At this point it can’t be changed.

It’s not specified by Intel or anything, so it’s quite possible that there
are other x86 implementations (that don’t strive for ABI compatibility
with GCC) that uses a different type. For example, I don’t know for
certain whether anyone’s verified that MSVC uses char* for va_list.