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;
}