|
Apple LLVM4.0 has supported the C11 standard key features - generics mechanism. Although the C11 in a generic mechanism than C ++ seem to be a lot of simple, but when doing library is still very useful.
Here we look at the C11 standard generic expression.
C11 Generics mechanisms are introduced by the keyword _Generic, its syntax is:
_Generic (Assignment-expression, generic-assoc-list)
generic-assoc-list:
generic-association
generic-assoc-list, generic-association
generic-association:
type-name: assignment-expression
default: assignment-expression
C code examples are given below:
#define GENERAL_ABS (x) _Generic ((x), int: abs, float: fabsf, double: fabs) (x)
static void GenericTest (void)
{
printf ( "int abs:% d \ n", GENERAL_ABS (-12));
printf ( "float abs:% f \ n", GENERAL_ABS (-12.04f));
printf ( "double abs:% f \ n", GENERAL_ABS (-13.09876));
int a = 10;
int b = 0, c = 0;
_Generic (A + 0.1f, int: b, float: c, default: b) ++;
printf ( "b =% d, c =% d \ n", b, c);
_Generic (A + = 1.1f, int: b, float: c, default: b) ++;
printf ( "a =% d, b =% d, c =% d \ n", a, b, c);
}
It should be noted here, _Generic in the assignment-expression just get it done and not the type to run the calculation. That is, the compiler just get the type of the expression at compile time, without any other instructions. This with sizeof (), typeof (), as well as in C ++ typeid () and decltype () the same.
In addition, there must be assignment-expression with the same type of generic-association generic-association-list, otherwise the compiler will complain. Of course, if it contains default processing in generic-association-list, then the compiler can be carried out smoothly. As shown in the following code:
struct MyStruct {int a, b;} s;
_Generic ( "Hello", const char *: puts ( "OK!")); // ERROR "Hello" to char [6] type!
_Generic ( "Hello", char [6]: "! OK" puts ()); // OK
_Generic ((Const char *) "Hello", const char *: puts ( "OK!")); // OK
_Generic (S, int: puts ( "OK!")); // ERROR
_Generic (S, struct MyStruct: puts ( "OK!")); // OK
_Generic (S, int: puts ( "! Yep"), default: puts ( "Others")); // OK
It should be noted that, _Generic expression, expression statement are not met for a match will also be the type of compiler, to confirm its effectiveness. Therefore, the type does not satisfy the matching expression like sizeof (), typeof (), as only the compiler, not calculation. For example, the following statement is all wrong:
const int g = 50;
typeof (g = 10) t = 200; // ERROR
int f = sizeof (g = 100); // ERROR
f = _Generic (g, int: sizeof (g), char: (g = 100, g), default: g + 10); // ERROR
The last line of code, even if the char: This type is not matched, but the compiler will still complain. |
|
|
|