Use lambdas (no portable)
En lugar de
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;}));
o (llvm con soporte de bloques)
qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});
prueba algo como
qsort(a,b,4,"\x8b\7+\6\xc3");
... donde la cadena entre comillas contiene las instrucciones del lenguaje máquina de su función "lambda" (conforme a todos los requisitos ABI de la plataforma).
Esto funciona en entornos en los que las constantes de cadena se marcan como ejecutables. Por defecto, esto es cierto en Linux y OSX pero no en Windows.
Una forma tonta de aprender a escribir sus propias funciones "lambda" es escribir la función en C, compilarla, inspeccionarla con algo parecido objdump -D
y copiar el código hexadecimal correspondiente en una cadena. Por ejemplo,
int f(int*a, int*b){return *a-*b;}
... cuando se compila gcc -Os -c
para un objetivo Linux x86_64 genera algo como
0: 8b 07 mov (%rdi),%eax
2: 2b 06 sub (%rsi),%eax
4: c3 retq
GNU CC goto
:
Puede llamar a estas "funciones lambda" directamente, pero si el código al que llama no toma parámetros y no va a regresar, puede usar goto
para guardar algunos bytes. Entonces en lugar de
((int(*)())L"ﻫ")();
o (si su entorno no tiene glifos árabes)
((int(*)())L"\xfeeb")();
Tratar
goto*&L"ﻫ";
o
goto*&L"\xfeeb";
En este ejemplo, eb fe
es lenguaje de máquina x86 para algo así for(;;);
y es un ejemplo simple de algo que no toma parámetros y no va a volver :-)
Resulta que puede goto
codificar que vuelve a un padre que llama.
#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));
}
El ejemplo anterior (podría compilarse y ejecutarse en Linux con gcc -O
) es sensible al diseño de la pila.
EDITAR: Dependiendo de su cadena de herramientas, es posible que deba usar el -zexecstack
indicador de compilación.
Si no es evidente de inmediato, esta respuesta se escribió principalmente para los lols. No me hago responsable de jugar golf mejor o peor o de resultados psicológicos adversos al leer esto.