Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Understanding void.h

Name: Anonymous 2016-01-25 19:02

So i've checked FV github to see it was empty.
Apparently FV is too stupid to use git and keeps void.h in gists.
From https://gist.github.com/FrozenVoid/87e6ad6212ac9ce496e0

1.The thing you notice first is everything depends on _VFUNC which actually does nothing but concatenate with ##
Its in varmacro.h and the system is based on http://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments bruteforce approach that creates a macro for every number of arguments. Its cute but limited to 63 arguments and requires writing 63 macros each time: he used this approach in early commits in the gist file.
What FV has done is to replace the 63 macros per macro with apply: same 63 macros but they carry a function macro as first argument and switch to next apply(N-1) with remaining arguments. There are several of these apply functions, most of them i couldn't understand, before writing some test code.
apply.h and apply2.h are the largest files in there along with argmacro.h.

2. _Generic abuse. If you preprocess the files which use p() macro the horrible mess of nested _Generics comes to front, hidden in type selection macro: the type selection...is just macro applied to the type list, another _Generic macro that has all the types.

3.tuple.h this one is quite interesting: using macro argument lists kept in parens as compile-time objects. The next trick is converting the "tuple" back into argument list:
Its not in tuple.h but counter-intuitevely in varmacro.h

#define wrap(...) __VA_ARGS__
#define detuple(...) wrap __VA_ARGS__
Basically when a "tuple" like (1,2,3) is passed to detuple it strips the parens off it, because wrap assumes the parens are its arguments and returns them back.
4.There are actually car and cdr in there: in the argmacro.h there is curious "rest" macro that strips off the first N arguments from its arguments and frontrest macro which return back first N arguments.
They apparently work by passing the argument list N times so it either cut N front arguments or preserves the N first arguments. Neat.

5.The key of array.h - the foreach macro: i was first curious how it find out the size of array, the trick he used is in mem.h elems() macro that uses size() a dirty macro hack that either returns sizeof or msize(): a call to check heap object length in bytes if its sizeof() equal to size of pointer. Here it is:
#define size1(arg1) ({u8 lensize=sizeof(arg1);\
once;\
if((lensize!=sizeof(vp)))break;\
if(isarray(arg1)|isbasic(arg1)){;break;};\
lensize=msize((vp)(u8)arg1);endonce;\
;lensize;})
void.h isn't that cryptic as it seemed at first glance.

Name: Anonymous 2016-11-18 10:17

Apparently FV is too stupid to use git
Because after i tried to install to bloated Github desktop for windows they shilled, i decided to use it as pastebin with revision control instead. I don't feel like using bloatware.
Basically when a "tuple" like (1,2,3) is passed to detuple it strips the parens off it
Actually detuple uses the trick that func_call (arguments) is the same as func_call (tuple) : the tuple just becomes arguments and the parens evaporate with function macro expanded.
There is nothing magical in detuple at all: it just unsafe to use it directly to remove parens, there is safedetuple that checks if the argument is actually a tuple or not(by speculatively expanding it and counting the resulting arguments(with nargs/reduce1arg:1+ args reduces to 1,0 to 0) :
#define istuple(tupletest...) reduce1arg(nargs(detuple(tupletest)))
#define safedetuple(possibletuple...) _VFUNC(detuple,istuple(possibletuple))(possibletuple)
nested _Generics
the GCC intrinsic is way worse(imagine the below nested 4 levels):
#define foo(x) \
({ \
typeof (x) tmp = (x); \
if (__builtin_types_compatible_p (typeof (x), long double)) \
tmp = foo_long_double (tmp); \
else if (__builtin_types_compatible_p (typeof (x), double)) \
tmp = foo_double (tmp); \
else if (__builtin_types_compatible_p (typeof (x), float)) \
tmp = foo_float (tmp); \
else \
abort (); \
tmp; \
})

The key of array.h - the foreach macro:
I've explained it here: http://bbs.progrider.org/prog/read/1479394498/14 since it comes up often

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List