Используйте лямбды (непортативно)
Вместо
f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);
или (только gcc)
qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));
или (llvm с поддержкой блоков)
qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});
попробуй что-то вроде
qsort(a,b,4,"\x8b\7+\6\xc3");
... где строка в кавычках содержит инструкции на машинном языке вашей функции "лямбда" (соответствует всем требованиям ABI платформы).
Это работает в средах, в которых строковые константы помечены как исполняемые. По умолчанию это верно для Linux и OSX, но не для Windows.
Один глупый способ научиться писать свои собственные «лямбда-функции» - это написать функцию в C, скомпилировать ее, проверить что-то вроде этого objdump -D
и скопировать соответствующий шестнадцатеричный код в строку. Например,
int f(int*a, int*b){return *a-*b;}
... при компиляции с gcc -Os -c
целью Linux x86_64 генерирует что-то вроде
0: 8b 07 mov (%rdi),%eax
2: 2b 06 sub (%rsi),%eax
4: c3 retq
GNU CC goto
:
Вы можете вызывать эти «лямбда-функции» напрямую, но если код, который вы вызываете, не принимает параметры и не собирается возвращаться, вы можете использовать goto
для сохранения несколько байтов. Так что вместо
((int(*)())L"ﻫ")();
или (если в вашей среде нет арабских символов)
((int(*)())L"\xfeeb")();
Пытаться
goto*&L"ﻫ";
или же
goto*&L"\xfeeb";
В этом примере eb fe
это машинный язык x86 для чего-то подобного for(;;);
и простой пример чего-то, что не принимает параметров и не собирается возвращать :-)
Оказывается, вы можете goto
написать код, который возвращается к вызывающему родителю.
#include<stdio.h>
int f(int a){
if(!a)return 1;
goto*&L"\xc3c031"; // return 0;
return 2; // never gets here
}
int main(){
printf("f(0)=%d f(1)=%d\n",f(0),f(1));
}
Приведенный выше пример (может компилироваться и запускаться в Linux с gcc -O
) чувствителен к макету стека.
РЕДАКТИРОВАТЬ: В зависимости от вашей цепочки инструментов, вам, возможно, придется использовать -zexecstack
флаг компиляции.
Если это не сразу видно, этот ответ был написан в основном для lols. Я не беру на себя ответственности за лучшее или худшее гольф или неблагоприятные психологические последствия от чтения этого.