Usa lambda (non portabile)
Invece di
f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);
o (solo gcc)
qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));
oppure (llvm con supporto dei blocchi)
qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});
prova qualcosa del genere
qsort(a,b,4,"\x8b\7+\6\xc3");
... dove la stringa tra virgolette contiene le istruzioni del linguaggio macchina della funzione "lambda" (conforme a tutti i requisiti ABI della piattaforma).
Funziona in ambienti in cui le costanti di stringa sono contrassegnate come eseguibili. Per impostazione predefinita, questo è vero in Linux e OSX ma non in Windows.
Un modo sciocco per imparare a scrivere le tue funzioni "lambda" è scrivere la funzione in C, compilarla, ispezionarla con qualcosa di simile objdump -D
e copiare il corrispondente codice esadecimale in una stringa. Per esempio,
int f(int*a, int*b){return *a-*b;}
... quando compilato gcc -Os -c
per un target x86_64 di Linux genera qualcosa di simile
0: 8b 07 mov (%rdi),%eax
2: 2b 06 sub (%rsi),%eax
4: c3 retq
GNU CC goto
:
Puoi chiamare queste "funzioni lambda" direttamente ma se il codice che stai chiamando non accetta parametri e non restituirà, puoi usare goto
per salvare qualche byte. Quindi invece di
((int(*)())L"ﻫ")();
o (se il tuo ambiente non ha glifi arabi)
((int(*)())L"\xfeeb")();
Provare
goto*&L"ﻫ";
o
goto*&L"\xfeeb";
In questo esempio, eb fe
è il linguaggio macchina x86 per qualcosa di simile for(;;);
ed è un semplice esempio di qualcosa che non accetta parametri e non restituirà :-)
Si scopre che è possibile goto
codificare che ritorna a un genitore chiamante.
#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));
}
L'esempio sopra (potrebbe essere compilato ed eseguito su Linux con gcc -O
) è sensibile al layout dello stack.
EDIT: a seconda della tua toolchain, potresti dover usare il -zexecstack
flag di compilazione.
Se non è immediatamente evidente, questa risposta è stata scritta principalmente per i lols. Non mi assumo alcuna responsabilità per il golf migliore o peggiore o per risultati psicologici avversi dalla lettura di questo.