lanzafame
2/24/2015 - 11:38 AM

worst_practices_in_gcc.c

The guide to getting fired: horrendous abuses of GCC.

For fun only: most of what is listed here are undefined with respect to the C standard, hence for obvious reasons they are not portable (sigh of relief comming from audience).
Tested with GCC (and codepad), so use #ifdef __GNUC__ to enclose all of these examples.

1: Map - Reduce in C ... as Macros ...
	#define MAP(fn, ret_type, fst, ...) ({ \
		  typeof(fst) from[] = {(fst), __VA_ARGS__ }; \
		  ret_type to[sizeof(from)/sizeof(typeof(fst))]; \
		  int i, n = sizeof(from)/sizeof(typeof(fst)); \
		  for(i=0;i<n;i++) to[i]=(fn)(from[i]); \
		  &to;}) \

	// MAP(atoi, int, "1", "2", "3", "4", "5")

	#define FOLD(fn, acc, fst, ...) ({ \
		  typeof(fst) from[] = {(fst), __VA_ARGS__ }; \
		  typeof(acc) accumulator = acc; \
		  int i, n = sizeof(from)/sizeof(typeof(fst)); \
		  for(i=0;i<n;i++) accumulator = (fn)(accumulator, from[i]); \
		  accumulator;}) \
		  
	// FOLD(add, 0., 1, 2, 3, 4, 5);

2: Casting functions into char* pointers
	char* code = (char*)(&add); // I don't know why you would ever need to...


or casting pointers of other types into function pointers (On x86 machines):

	The following will actually run:
		int eax = ((int(*)())("\xc3"))()

	This will return the immediate value of the EAX register when called

	Even worse, writing the swap function in machine code 

		int a = 10, b = 20;
		((void(*)(int,int))"\x8b\x44\x24\x04\x8b\x5c\x24\x08\x8b\x00\x8b\x1b\x31\xc3\x31\xd8\x31\xc3\x8b\x4c\x24\x04\x89\x01\x8b\x4c\x24\x08\x89\x19\xc3")(a,b);

	A for-loop to 1000:
		((int(*)())"\x66\x31\xc0\x8b\x5c\x24\x04\x66\x40\x50\xff\xd3\x58\x66\x3d\xe8\x03\x75\xf4\xc3")(&function); // calls function with 1->1000

	Recursion (repeatedly checks if %eax is >= 100)
		const char* lol = "\x8b\x5c\x24\x4\x3d\xe8\x3\x0\x0\x7e\x2\x31\xc0\x83\xf8\x64\x7d\x6\x40\x53\xff\xd3\x5b\xc3\xc3\x5d\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\xb8\xce\x83\x4";
		i = ((int(*)(int*))(lol))(lol);