diff options
| author | FreeArtMan <dos21h@gmail.com> | 2017-10-09 01:25:56 +0100 | 
|---|---|---|
| committer | FreeArtMan <dos21h@gmail.com> | 2017-10-09 01:25:56 +0100 | 
| commit | b8657880fb0ef8720d4edaae52bd5cf2a58ca275 (patch) | |
| tree | b41df15a8b98c2798b9d7dd4ba148a5ab91dd3d0 /md/writeup | |
| parent | 601377f2af4a566422740e8716b3815e90722d9f (diff) | |
| download | md-content-b8657880fb0ef8720d4edaae52bd5cf2a58ca275.tar.gz md-content-b8657880fb0ef8720d4edaae52bd5cf2a58ca275.zip  | |
Added notes about _Generic's
Diffstat (limited to 'md/writeup')
| -rw-r--r-- | md/writeup/c_macro_tricks.md | 128 | 
1 files changed, 128 insertions, 0 deletions
diff --git a/md/writeup/c_macro_tricks.md b/md/writeup/c_macro_tricks.md index 759cf70..4068272 100644 --- a/md/writeup/c_macro_tricks.md +++ b/md/writeup/c_macro_tricks.md @@ -250,5 +250,133 @@ void mul ( "there is 3");  void div ( "there is 1");  ``` +## C11 generics +### Match single argument +Best part of it that it can match also typdefed structures. So now macroses  +can contain typechecking + +``` +#define type_str(T) _Generic( (T), int: "int",\ +long: "long",\ +A: "A",\ +default: "Unknown type") +``` + +#### Source +```c +typedef struct A +{ + +} A; + +#define type_str(T) _Generic( (T), int: "int",\ +long: "long",\ +A: "A",\ +default: "Unknown type") + +int main() +{ +  A a; +  printf("%s\n",type_str((long)1)); +  printf("%s\n",type_str((int)1)); +  printf("%s\n",type_str(a)); +} +``` + +#### Result + +``` +long +int +A +``` + +### Match multiple arguments + +``` +#define type_str(T1,T2) _Generic( (T1),\ +int:   _Generic((T2),int:"int int",   long: "int long",   float: "int float",   A: "int A",   default: "int UNK"),\ +long:  _Generic((T2),int:"long int",  long: "long long",  float: "long float",  A: "long A",  default: "long UNK"),\ +float: _Generic((T2),int:"float int", long: "float long", float: "float float", A: "float A", default: "float UNK"),\ +A:     _Generic((T2),int:"A int",     long: "A long",     float: "A float",     A: "A A",     default: "A UNK"),\ +default: "UNK UNK" ) +``` + +#### Source +``` +typedef struct A +{ + +} A; + +#define type_str(T1,T2) _Generic( (T1),\ +int:   _Generic((T2),int:"int int",   long: "int long",   float: "int float",   A: "int A",   default: "int UNK"),\ +long:  _Generic((T2),int:"long int",  long: "long long",  float: "long float",  A: "long A",  default: "long UNK"),\ +float: _Generic((T2),int:"float int", long: "float long", float: "float float", A: "float A", default: "float UNK"),\ +A:     _Generic((T2),int:"A int",     long: "A long",     float: "A float",     A: "A A",     default: "A UNK"),\ +default: "UNK UNK" ) + +int main() +{ +  A a; +  printf("%s\n",type_str((long)1,1.f)); +  printf("%s\n",type_str((int)1,1)); +  printf("%s\n",type_str(a,a)); +} + +``` + +#### Result + +``` +long float +int int +A A +``` +### Generic printf +``` +#define FF "%f " +#define FS "%s " +#define FD "%d " +#define N "" +#define PR2(S,T,T1,T2,...) printf(S,T,T1) +#define PR1(S,T,T1,...) _Generic((T1),\ +  int:  PR2(S FD,T,T1,__VA_ARGS__,N,N,N),\ +  float:PR2(S FF,T,T1,__VA_ARGS__,N,N,N),\ +  char*:PR2(S FS,T,T1,__VA_ARGS__,N,N,N),\ +  default:"") +#define static_printf(T1,...) _Generic((T1),\  +  int:  PR1(FD,T1,__VA_ARGS__,N,N,N),\ +  float:PR1(FF,T1,__VA_ARGS__,N,N,N),\ +  char*:PR1(FS,T1,__VA_ARGS__,N,N,N),\ +  default:"") +``` + +#### Source +``` +int main() +{ +  A a; +  int b = 3, c = 4; +  static_printf(1, 2.f); +  printf("\n"); +  static_printf(b,c); +  printf("\n"); + +  static_printf("big float",0.01f); +  printf("\n"); +} +``` + +#### Result + +``` +1 2.000000  +3 4  +big float  0.010000 +``` + +## Links +1. [https://baike.baidu.com/item/C11](https://baike.baidu.com/item/C11)  | 
