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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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[].

--
Matthew
Please do not quote my e-mail address unobfuscated in message bodies.
--
No .sig for you! NEXT! -- Unknown
#include <stdio.h>

#define TEST(a,b) printf("%s, %s => %s\n", #a, #b, __builtin_choose_expr(__builtin_types_compatible_p(a,b),"true","false"))

int main() {
  TEST(char*, char*);
  TEST(char*, const char*);
  TEST(const char*, char*);
  TEST(char[], char*);
  TEST(char*, char[]);
  TEST(char[], const char[]);
  TEST(typeof("hello"), char*);
  TEST(typeof("hello"), char[]);
  TEST(typeof("hello"), const char*);
  TEST(typeof("hello"), const char[]);
  TEST(typeof(&(*"hello")), char*);
  TEST(typeof(&(*"hello")), char[]);
  TEST(typeof(&(*"hello")), const char*);
  TEST(typeof(&(*"hello")), const char[]);
  TEST(typeof(*(&"hello")), char*);
  TEST(typeof(*(&"hello")), char[]);
  TEST(typeof(*(&"hello")), const char*);
  TEST(typeof(*(&"hello")), const char[]);
  TEST(typeof(&(("hello")[0])), char*);
  TEST(typeof(&(("hello")[0])), char[]);
  TEST(typeof(&(("hello")[0])), const char*);
  TEST(typeof(&(("hello")[0])), const char[]);

  char *char_ptr;
  const char *const_char_ptr;
  char char_arr[1];
  const char const_char_arr[1];

  TEST(typeof(&((char_ptr)[0])), char*);
  TEST(typeof(&((char_ptr)[0])), const char*);
  TEST(typeof(&((const_char_ptr)[0])), char*);
  TEST(typeof(&((const_char_ptr)[0])), const char*);
  TEST(typeof(&((char_arr)[0])), char*);
  TEST(typeof(&((char_arr)[0])), const char*);
  TEST(typeof(&((const_char_arr)[0])), char*);
  TEST(typeof(&((const_char_arr)[0])), const char*);
  return 0;
}


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux