-
Notifications
You must be signed in to change notification settings - Fork 0
/
t_Generic.c
90 lines (80 loc) · 3.56 KB
/
t_Generic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
# error "_Generic is not supported until ISO C11"
#endif
/* messing with C11 _Generic() */
/* see also: http://www.robertgamble.net/2012/01/c11-generic-selections.html */
#define typename(x) _Generic((x), /* Get the name of a type */ \
\
_Bool: "_Bool", unsigned char: "unsigned char", \
char: "char", signed char: "signed char", \
short int: "short int", unsigned short int: "unsigned short int", \
int: "int", unsigned int: "unsigned int", \
long int: "long int", unsigned long int: "unsigned long int", \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
float: "float", double: "double", \
long double: "long double", char *: "pointer to char", \
void *: "pointer to void", int *: "pointer to int", \
const char *: "const pointer to char", \
default: "other")
#define fmt "%25s is '%s'\n"
int main(void);
int
main()
{
size_t s __unused;
ptrdiff_t p __unused;
intmax_t i __unused;
int ai[3] __unused = {0};
int *pi __unused;
bool b __unused = false;
char c __unused = 'c';
signed char sc __unused = 's';
unsigned char uc __unused = 'u';
const char *cs __unused = "foobarnone";
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
nullptr_t np = nullptr;
#endif
printf(
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
fmt fmt
#endif
fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt fmt
fmt fmt fmt fmt fmt,
#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 202000L
"nullptr_t", typename(np),
"nullptr", typename(nullptr),
#endif
"size_t", typename(s),
"ptrdiff_t", typename(p),
"intmax_t", typename(i),
"char", typename(c),
"signed char", typename(sc),
"unsigned char", typename(uc),
"char constant", typename('0'), /* xxx the usual conversions give int! */
"signed char constant", typename((signed char) '0'), /* casts do not!! */
"unsigned char constant", typename((unsigned char) '0'), /* casts do not!! */
"character string constant", typename("foobar"),
"const char string", typename(cs),
"0", typename(0),
"NULL", typename(NULL),
"0x7FFFFFFF", typename(0x7FFFFFFF), /* sign detection? */
"0xFFFFFFFF", typename(0xFFFFFFFF), /* sign detection? */
"0x7FFFFFFFU", typename(0x7FFFFFFFU),
"array of int", typename(ai),
"pointer to int", typename(pi),
"true", typename(true), /* XXX the usual conversions give int! */
"false", typename(false), /* XXX the usual conversions give int! */
"bool", typename(b)); /* !!! no "usual conversions"! */
exit(EXIT_SUCCESS);
}
/*
* Local Variables:
* eval: (make-local-variable 'compile-command)
* compile-command: (let ((fn (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))) (concat "rm -f " fn "; " (default-value 'compile-command) " CSTD=c11 " fn " && ./" fn))
* End:
*/