P
Prathamesh Kulkarni
I was reading this article (http://www.robertgamble.net/2012/01/c11-generic-selections.html), on _Generic.
The author shows a printnl() macro, which fails to compile if the controlling expression is a constant string, and the generic association is char *
Here's a simplified test-case:
int
main(void)
{
int a = _Generic("hello", char *: 1);
}
I used clang-3.2 to compile.
f.c:5:20: error: controlling expression type 'char [6]' not compatible withany generic association type
int a = _Generic("hello", char *: 1);
A possible work-around mentioned in the article:
int a = _Generic((char *) "hello", char *: 1);
Another work-around (http://stackoverflow.com/questions/18857056/c11-generic-how-to-deal-with-string-literals):
int a = _Generic((0, "hello"), char *: 1);
I am not able to understand why does the code compile to fail without the
workarounds. n1570 p 6.3.2, 3rd point (page 54) states:
Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
This clause has no mention for _Generic, so shouldn't the type of
"hello" be converted from char[6], to char * when it's used as a controlling expression ?
(the author of the above mentioned article raises the same issue but didn'tpursue it further).
Thanks and Regards,
Prathamesh
The author shows a printnl() macro, which fails to compile if the controlling expression is a constant string, and the generic association is char *
Here's a simplified test-case:
int
main(void)
{
int a = _Generic("hello", char *: 1);
}
I used clang-3.2 to compile.
f.c:5:20: error: controlling expression type 'char [6]' not compatible withany generic association type
int a = _Generic("hello", char *: 1);
A possible work-around mentioned in the article:
int a = _Generic((char *) "hello", char *: 1);
Another work-around (http://stackoverflow.com/questions/18857056/c11-generic-how-to-deal-with-string-literals):
int a = _Generic((0, "hello"), char *: 1);
I am not able to understand why does the code compile to fail without the
workarounds. n1570 p 6.3.2, 3rd point (page 54) states:
Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
This clause has no mention for _Generic, so shouldn't the type of
"hello" be converted from char[6], to char * when it's used as a controlling expression ?
(the author of the above mentioned article raises the same issue but didn'tpursue it further).
Thanks and Regards,
Prathamesh