Verwenden Sie Lambdas (nicht portierbar)
Anstatt von
f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);
oder (nur gcc)
qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));
oder (llvm with blocks support)
qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});
versuchen Sie etwas wie
qsort(a,b,4,"\x8b\7+\6\xc3");
... wobei die angeführte Zeichenfolge die maschinensprachlichen Anweisungen Ihrer "Lambda" -Funktion enthält (gemäß allen Anforderungen der Plattform ABI).
Dies funktioniert in Umgebungen, in denen Zeichenfolgenkonstanten als ausführbar markiert sind. Standardmäßig gilt dies für Linux und OSX, nicht jedoch für Windows.
Eine dumme Methode, um zu lernen, wie man eigene "Lambda" -Funktionen schreibt, besteht darin, die Funktion in C zu schreiben, zu kompilieren, sie mit etwas ähnlichem zu untersuchen objdump -D
und den entsprechenden Hex-Code in eine Zeichenfolge zu kopieren. Zum Beispiel,
int f(int*a, int*b){return *a-*b;}
... wenn es gcc -Os -c
für ein Linux x86_64-Ziel kompiliert wird, erzeugt es so etwas wie
0: 8b 07 mov (%rdi),%eax
2: 2b 06 sub (%rsi),%eax
4: c3 retq
GNU CC goto
:
Sie können diese "Lambda-Funktionen" direkt aufrufen, aber wenn der aufgerufene Code keine Parameter annimmt und nicht zurückgibt, können Sie goto
ein paar Bytes sparen. Also statt
((int(*)())L"ﻫ")();
oder (wenn Ihre Umgebung keine arabischen Glyphen enthält)
((int(*)())L"\xfeeb")();
Versuchen
goto*&L"ﻫ";
oder
goto*&L"\xfeeb";
In diesem Beispiel eb fe
ist x86 Maschinensprache für so etwas wie for(;;);
und ein einfaches Beispiel für etwas, das keine Parameter akzeptiert und nicht zurückkehren wird :-)
Es hat sich herausgestellt, dass Sie goto
Code verwenden können, der an einen anrufenden Elternteil zurückgegeben wird.
#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));
}
Das obige Beispiel (kann unter Linux kompiliert und ausgeführt werden gcc -O
) ist abhängig vom Stack-Layout.
BEARBEITEN: Abhängig von Ihrer Toolchain müssen Sie möglicherweise das -zexecstack
Kompilierungsflag verwenden.
Wenn es nicht sofort ersichtlich ist, wurde diese Antwort hauptsächlich für die Lols geschrieben. Ich übernehme keine Verantwortung für besseres oder schlechteres Golfen oder negative psychologische Ergebnisse, wenn ich dies lese.