rules for __builtin_types_compatible_p?? (was: __builtin_types_compatible_p and 'char *' vs. 'char []')

Matthew Woehlke
Fri Nov 7 20:26:00 GMT 2008

Kevin P. Fleming wrote:
> Matthew Woehlke wrote:
>> static inline s_or(char* a, char* b) {
>>   return ast_strlen_zero(a) ? b ? a);
>> }
>> static inline s_or_const(const char* a, const char* b) {
>>   return ast_strlen_zero(a) ? b ? a);
>> }
>> #define S_OR(a,b) \
>> __builtin_choose_expr( \
>>   __builtin_types_compatible_p(typeof(a), char*) && \
>>   __builtin_types_compatible_p(typeof(b), char*), \
>>   s_or(a,b), s_or_const(a,b))
> Unfortunately the documentation says the 'compatible determination
> ignores attributes like const, volatile, etc. I'll give it a try though,
> it's easy enough to test.

Hmm. I did actually test it before posting, though now that I tried a 
few more variations, I am getting some odd results:

char*, char* => true (you'd hope!)
char*, const char* => false (ok, good for our purposes, but...)
char[], char* => false (eh?)
char[], const char[] => true (um...)
typeof("hello"), char* => false (likewise, eh?)
typeof("hello"), char[] => true (ok)
typeof("hello"), const char* => false (hrm...)
typeof("hello"), const char[] => true (not helping, is it?)
typeof(&(*"hello")), char* => true (ah...)
typeof(&(*"hello")), char[] => false (curious...)
typeof(&(*"hello")), const char* => false (wtf, gcc ate a 'const'?)
typeof(&(*"hello")), const char[] => false (figures...)

So... I'm not sure what rules are in place here. Contrary to your 
original report, my gcc (gcc (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)) 
seems to consider arrays and pointers incompatible (eh?), same-type 
arrays compatible regardless of qualifiers, but cares about the 
qualifiers when dealing with pointers. And seems to misplace a const 
when taking the address of an immutable char.

This behavior doesn't strike me as very useful...

typeof(&(("hello")[0])), char* => false (not surprising?)
typeof(&(("hello")[0])), char[] => false (or is it?)
typeof(&(("hello")[0])), const char* => true (hey! this looks useful!)
typeof(&(("hello")[0])), const char[] => false (and... not surprising)

...but this ("typeof(&((b)[0]))") seems like it might work, assuming 
that "b" is a string literal, a [const] char*, or a [const] char[].

Please do not quote my e-mail address unobfuscated in message bodies.
No .sig for you! NEXT! -- Unknown
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: tc.c
URL: <>

More information about the Gcc-help mailing list