--- /dev/null
+// scope
+
+int main(void) {
+ int i = 1024;
+
+ {
+ int i = 2048;
+ expecti(i, 2048);
+ i = 4096;
+ }
+
+ expecti(i, 1024);
+
+ {
+ int i = 4096;
+ expecti(i, 4096);
+ i = 2046;
+ }
+
+ expecti(i, 1024);
+
+ return 0;
+}
--- /dev/null
+// sizeof operator
+
+int main(void) {
+ expecti(sizeof(char), 1);
+ expecti(sizeof(short), 2);
+ expecti(sizeof(int), 4);
+ expecti(sizeof(long), 8);
+ expecti(sizeof(char*), 8);
+ expecti(sizeof(short*), 8);
+ expecti(sizeof(int*), 8);
+ expecti(sizeof(long*), 8);
+
+ expecti(sizeof(unsigned char), 1);
+ expecti(sizeof(unsigned short), 2);
+ expecti(sizeof(unsigned int), 4);
+ expecti(sizeof(unsigned long), 8);
+
+ expecti(sizeof 1, 4);
+ expecti(sizeof 1L, 8);
+ expecti(sizeof 1.0f, 4);
+ expecti(sizeof 1.0, 8);
+ expecti(sizeof 'a', 4);
+ expecti(sizeof('b'), 4);
+
+ expecti(sizeof(char[1]), 1);
+ expecti(sizeof(char[2]), 2);
+ expecti(sizeof(char[3]), 3);
+ expecti(sizeof(char[1][10]), 10);
+ expecti(sizeof(char[10][1]), 10);
+ expecti(sizeof(char[10][10]), 100);
+ expecti(sizeof(int[4][2]), 32);
+ expecti(sizeof(int[2][4]), 32);
+
+ char a[] = { 1, 2, 3 };
+ char b[] = "abc";
+ char *c[5];
+ char *(*d)[3];
+
+ expecti(sizeof(a), 3);
+ expecti(sizeof(b), 4);
+ expecti(sizeof(c), 40);
+ expecti(sizeof(d), 8);
+ expecti(sizeof(*d), 24);
+ expecti(sizeof(**d), 8);
+ expecti(sizeof(***d), 1);
+
+ char _not_int_;
+ expecti(sizeof((int)_not_int_), 4); // cast makes it sizeof(int)
+
+ // the more complicated syntax cases
+ expecti(sizeof(b[0]), 1);
+ expecti(sizeof((b[0])), 1);
+ expecti(sizeof((b)[0]), 1);
+ expecti(sizeof(((b)[0])), 1);
+
+ return 0;
+}
--- /dev/null
+// static assertions
+
+int main(void) {
+ _Static_assert(1, "failed");
+
+ struct {
+ _Static_assert(1, "failed");
+ } _;
+
+ return 0;
+}
--- /dev/null
+// structures
+
+struct A {
+ int a;
+ struct {
+ char b;
+ int c;
+ } y;
+} A;
+
+struct B {
+ int a;
+} B;
+
+struct C {
+ int a;
+ int b;
+} C;
+
+int main(void) {
+ struct {
+ int a;
+ } a;
+ a.a = 1024;
+ expecti(a.a, 1024);
+
+ struct {
+ int a;
+ int b;
+ } b;
+ b.a = 1024;
+ b.b = 2048;
+ expecti(b.a, 1024);
+ expecti(b.b, 2048);
+
+ struct {
+ int a;
+ struct {
+ char b;
+ int c;
+ } b;
+ } c;
+ c.a = 1024;
+ c.b.b = 32;
+ c.b.c = 2048;
+ expecti(c.a, 1024);
+ expecti(c.b.b, 32);
+ expecti(c.b.c, 2048);
+
+ struct name1 {
+ int a;
+ struct {
+ char b;
+ int c;
+ } b;
+ };
+ struct name1 d;
+ d.a = 16;
+ d.b.b = 32;
+ d.b.c = 64;
+ expecti(d.a, 16);
+ expecti(d.b.b, 32);
+ expecti(d.b.c, 64);
+
+ struct name2 {
+ int a;
+ int b;
+ } e;
+ struct name2 *f = &e;
+
+ // obj->ptr
+ e.a = 128;
+ expecti((*f).a, 128);
+
+ // ptr->obj
+ (*f).a = 256;
+ expecti(e.a, 256);
+
+ // again
+ e.b = 64;
+ expecti((*f).b, 64);
+
+ (*f).b = 128;
+ expecti(e.b, 128);
+
+ // over read?
+ struct {
+ int a[3];
+ int b[3];
+ } g;
+ g.a[0] = 1024;
+ g.b[1] = 2048;
+ expecti(g.a[0], 1024);
+ expecti(g.b[1], 2048);
+ expecti(g.a[4], 2048); // &g.a[4] == &g.b[0]
+
+ A.a = 64;
+ A.y.b = 65;
+ A.y.c = 256;
+ expecti(A.a, 64);
+ expecti(A.y.b, 65);
+ expecti(A.y.c, 256);
+
+ struct B *h = &B;
+ B.a = 128;
+ expecti((*h).a, 128);
+ expecti(B.a, 128);
+ expecti(h->a, 128);
+
+ h->a = 256;
+ expecti((*h).a, 256);
+ expecti(B.a, 256);
+ expecti(h->a, 256);
+
+ struct C i[3];
+ i[0].a = 32;
+ expecti(i[0].a, 32);
+ i[0].b = 64;
+ expecti(i[0].b, 64);
+ i[1].b = 128;
+ expecti(i[1].b, 128);
+ int *j = i;
+ expecti(j[3], 128); // &j[3] == &i[1].b
+
+ struct { char c; } k = { 'a' };
+ expecti(k.c, 'a');
+
+ struct { int a[3]; } l = { { 1, 2, 3 } };
+ expecti(l.a[0], 1);
+ expecti(l.a[1], 2);
+ expecti(l.a[2], 3);
+
+ // unnamed shit
+ struct {
+ union {
+ struct {
+ int x;
+ int y;
+ };
+ struct {
+ char c[8];
+ };
+ };
+ } m;
+ m.x = 10;
+ m.y = 20;
+ expecti(m.c[0], 10);
+ expecti(m.c[4], 20);
+
+ // structure copy via assignment
+ struct {
+ int a;
+ int b;
+ int c;
+ } X, Y, Z;
+ X.a = 8;
+ X.b = 16;
+ X.c = 32;
+ Y = X;
+ Z.a = 64;
+ Z.b = 128;
+ Z.c = 256;
+ expecti(Y.a, 8);
+ expecti(Y.b, 16);
+ expecti(Y.c, 32);
+ Y = Z;
+ expecti(Y.a, 64);
+ expecti(Y.b, 128);
+ expecti(Y.c, 256);
+
+ // arrows
+ struct cell {
+ int value;
+ struct cell *next;
+ };
+ struct cell aa = { 10, 0 };
+ struct cell bb = { 20, &aa };
+ struct cell cc = { 30, &bb };
+ struct cell *dd = &cc;
+
+ expecti(cc.value, 30);
+ expecti(dd->value, 30);
+ expecti(dd->next->value, 20);
+ expecti(dd->next->next->value, 10);
+
+ dd->value = 16;
+ dd->next->value = 32;
+ dd->next->next->value = 64;
+ expecti(dd->value, 16);
+ expecti(dd->next->value, 32);
+ expecti(dd->next->next->value, 64);
+
+ // addressing
+ struct super {
+ int a;
+ struct {
+ int b;
+ } y;
+ } poke = { 99, 100 };
+
+ int *poke1 = &poke.a;
+ int *poke2 = &poke.y.b;
+
+ expecti(*poke1, 99);
+ expecti(*poke2, 100);
+ expecti(*&poke.a, 99);
+ expecti(*&poke.y.b, 100);
+
+ struct super *inward = &poke;
+ int *poke3 = &inward->a;
+ int *poke4 = &inward->y.b;
+
+ expecti(*poke3, 99);
+ expecti(*poke4, 100);
+ expecti(*&inward->a, 99);
+ expecti(*&inward->y.b, 100);
+
+ // incomplete in the opposite direction
+ struct incomplete1;
+ struct incomplete2 {
+ struct incomplete1 *next;
+ };
+ struct incomplete1 {
+ int value;
+ };
+
+ struct incomplete1 in1 = { 3 };
+ struct incomplete2 in2 = { &in1 };
+
+ expecti(in2.next->value, 3);
+
+ struct {
+ int x;
+ } __a = {
+ 1024
+ }, *__b = &__a;
+ int *__c = &__b->x;
+
+ expecti(*__c, 1024);
+
+
+ // bit fields
+ union {
+ int i;
+ struct {
+ int a: 5;
+ int b: 5;
+ };
+ } bitfield;
+ bitfield.i = 0;
+ bitfield.a = 20;
+ bitfield.b = 15;
+ expecti(bitfield.i, 500); // (15 << 5) + 20 == 500
+
+ struct {
+ char a:4;
+ char b:4;
+ } bitfield2 = { 5, 10 };
+
+ expecti(bitfield2.a, 5);
+ expecti(bitfield2.b, 10);
+
+ union {
+ int a: 10;
+ char b: 5;
+ char c: 5;
+ } bitfield3;
+
+ bitfield3.a = 2;
+ expecti(bitfield3.a, 2);
+ expecti(bitfield3.b, 2);
+ expecti(bitfield3.c, 2);
+
+ struct __empty {};
+ expecti(sizeof(struct __empty), 0);
+
+ // FAMS
+ struct __fam0 { int a, b[]; };
+ struct __fam1 { int a, b[0]; };
+
+ expecti(sizeof(struct __fam0), 4);
+ expecti(sizeof(struct __fam1), 4);
+
+ struct __gccfam { int a[0]; };
+ expecti(sizeof(struct __gccfam), 0);
+
+ struct __famoverwrite { int a, b[]; };
+ struct __famoverwrite OV = { 1, 2, 3, 4, 5 };
+
+ expecti(OV.b[0], 2);
+ expecti(OV.b[1], 3);
+ expecti(OV.b[2], 4);
+ expecti(OV.b[3], 5);
+
+ return 0;
+}
--- /dev/null
+// typeof keyword
+
+int main(void) {
+ // basic usage of it
+ typeof(int) a = 1024;
+ expecti(a, 1024);
+
+ typeof(a) b = 2048;
+ expecti(b, 2048);
+
+ __typeof__(int) aa = 1024;
+ expecti(aa, 1024);
+
+ __typeof__(aa) bb = 2048;
+ expecti(bb, 2048);
+
+
+ // arrays?
+ char c[] = "hello";
+ typeof(c) d = "world";
+
+ expectstr(d, "world");
+ expecti(sizeof(d), 6);
+
+ typeof(typeof (char *)[4]) odd;
+ expecti(sizeof(odd)/sizeof(*odd), 4);
+
+
+ char cc[] = "hello";
+ __typeof__(cc) dd = "world";
+
+ expectstr(dd, "world");
+ expecti(sizeof(dd), 6);
+
+ __typeof__(__typeof__ (char *)[4]) oddd;
+ expecti(sizeof(oddd)/sizeof(*oddd), 4);
+
+ // struct union enum
+ typeof(struct { int a; }) __1 = { .a = 1 };
+ typeof(union { int a; }) __2 = { .a = 1 };
+ typeof(enum { A1,B2 }) __3 = { B2 };
+
+ expecti(__1.a, 1);
+ expecti(__2.a, 1);
+ expecti(__3, B2);
+
+ __typeof__(struct { int a; }) __11 = { .a = 1 };
+ __typeof__(union { int a; }) __22 = { .a = 1 };
+ __typeof__(enum { A11,B22 }) __33 = { B22 };
+
+ expecti(__11.a, 1);
+ expecti(__22.a, 1);
+ expecti(__33, B22);
+
+ return 0;
+}
--- /dev/null
+// types
+
+int main(void) {
+ char a;
+ short b;
+ int c;
+ long d;
+ long long e;
+ short int f;
+ long int g;
+ long long int f;
+ long int long g;
+ float h;
+ double i;
+ long double j;
+
+ signed char k;
+ signed short l;
+ signed int m;
+ signed long n;
+ signed long long o;
+ signed short int p;
+ signed long int q;
+ signed long long int r;
+
+ unsigned char s;
+ unsigned short t;
+ unsigned int u;
+ unsigned long v;
+ unsigned long long w;
+ unsigned short int x;
+ unsigned long int y;
+ unsigned long long int z;
+
+ static A;
+ auto B;
+ register C;
+ static int D;
+ auto int E;
+ register int F;
+
+ int *G;
+ int *H[5];
+ int (*I)[5];
+ expecti(sizeof(G), 8);
+ expecti(sizeof(H), 40);
+ expecti(sizeof(I), 8);
+
+ int unsigned auto* const* const* J;
+
+ typedef int K;
+ K L = 5;
+ expecti(L, 5);
+
+ typedef K M[3];
+ M N = { 1, 2, 3 };
+ expecti(N[0], 1);
+ expecti(N[1], 2);
+ expecti(N[2], 3);
+
+ typedef struct { int a; } O;
+ O P;
+ P.a = 64;
+ expecti(P.a, 64);
+
+ typedef int __take_precedence_1;
+ typedef int __take_precedence_2;
+ __take_precedence_1 __take_precedence_2 = 100;
+ expecti(__take_precedence_2, 100);
+
+ return 0;
+}
--- /dev/null
+// unions
+
+int global = 5;
+int *pointer = &global;
+
+int main(void) {
+ union {
+ int a;
+ int b;
+ } a = { 128 };
+
+ union {
+ char a[4];
+ int b;
+ } b = { .b = 0 };
+
+ b.a[1] = 1;
+
+ union {
+ char a[4];
+ int b;
+ } c = { 0, 1, 0, 0 };
+
+ expecti(a.b, 128);
+ expecti(b.b, 256);
+ expecti(c.b, 256);
+
+ expecti(*pointer, 5);
+
+ return 0;
+}
--- /dev/null
+// stdarg
+
+#include <stdarg.h>
+char buffer[1024];
+
+void testi(int a, ...) {
+ va_list ap;
+ va_start(ap, a);
+ expecti(a, 1);
+ expecti(va_arg(ap, int), 2);
+ expecti(va_arg(ap, int), 3);
+ expecti(va_arg(ap, int), 4);
+ expecti(va_arg(ap, int), 5);
+
+ va_end(ap);
+}
+
+void testf(float a, ...) {
+ va_list ap;
+ va_start(ap, a);
+
+ expectf(a, 1.0f);
+ expectf(va_arg(ap, float), 2.0f);
+ expectf(va_arg(ap, float), 4.0f);
+ expectf(va_arg(ap, float), 8.0f);
+
+ va_end(ap);
+}
+
+void testm(char *p, ...) {
+ va_list ap;
+ va_start(ap, p);
+
+ expectstr(p, "hello world");
+ expectf (va_arg(ap, float), 3.14);
+ expecti (va_arg(ap, int), 1024);
+ expectstr(va_arg(ap, char *), "good bye world");
+ expecti (va_arg(ap, int), 2048);
+
+ va_end(ap);
+}
+
+char *format(char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap); // fuck yeah
+ va_end(ap);
+ return buffer;
+}
+
+void testt(void) {
+ expectstr(format(""), ""); // nothing
+ expectstr(format("%d", 10), "10");
+ expectstr(
+ format("%d,%.1f,%d,%.1f,%s", 1024, 3.14, 2048, 6.28, "hello world"),
+ "1024,3.1,2048,6.3,hello world"
+ );
+}
+
+int main(void) {
+ testi(1, 2, 3, 4, 5);
+ testf(1.0f, 2.0f, 4.0f, 8.0f);
+ testm("hello world", 3.14, 1024, "good bye world", 2048);
+ testt();
+
+ return 0;
+}
--- /dev/null
+// arithmetic on void
+
+int main(void) {
+ expecti(sizeof(void), 1);
+ expecti(sizeof(main), 8); // sizeof function == sizeof(&function)
+ // i.e the function pointer for that
+ // function (GCC extension)
+
+ int a[] = { 1, 2, 3 };
+ void *p = (void*)a;
+
+ expecti(*(int*)p, 1); p += 4;
+ expecti(*(int*)p, 2); p += 4;
+ expecti(*(int*)p, 3);
+
+ return 0;
+}