Lambda kullan (taşınabilir değil)
Onun yerine
f(int*a,int*b){return*a>*b?1:-1;}
...
qsort(a,b,4,f);
veya (yalnızca gcc)
qsort(a,b,4,({int L(int*a,int*b){a=*a>*b?1:-1;}L;}));
veya (blok desteği olan llvm)
qsort_b(a,b,4,^(const void*a,const void*b){return*(int*)a>*(int*)b?1:-1;});
gibi bir şey dene
qsort(a,b,4,"\x8b\7+\6\xc3");
... burada alıntılanan dize "lambda" fonksiyonunuzun makine dili talimatlarını içerir (tüm platform ABI gereksinimlerine uygundur).
Bu, dize sabitlerinin çalıştırılabilir olarak işaretlendiği ortamlarda çalışır. Varsayılan olarak, bu Linux ve OSX'te geçerlidir ancak Windows'ta geçerlidir.
Kendi "lambda" işlevlerinizi yazmayı öğrenmenin saçma bir yolu, işlevi C'ye yazmak, onu derlemek, benzer bir şeyle incelemek objdump -Dve karşılık gelen hex kodunu bir dizeye kopyalamaktır. Örneğin,
int f(int*a, int*b){return *a-*b;}
... gcc -Os -cLinux için derlendiğinde x86_64 hedefi gibi bir şey üretir
0: 8b 07 mov (%rdi),%eax
2: 2b 06 sub (%rsi),%eax
4: c3 retq
GNU CC goto:
Bu "lambda işlevlerini" doğrudan çağırabilirsiniz ancak aradığınız kod parametreleri almazsa ve geri dönmezse, gotobirkaç bayttan tasarruf etmek için kullanabilirsiniz . Yani yerine
((int(*)())L"ﻫ")();
veya (çevrenizde Arapça glif yoksa)
((int(*)())L"\xfeeb")();
Deneyin
goto*&L"ﻫ";
veya
goto*&L"\xfeeb";
Bu örnekte, eb fex86 makine dili gibi for(;;);bir şeydir ve parametreleri almayan ve geri dönmeyecek olan şeylerin basit bir örneğidir :-)
gotoÇağıran bir ebeveyne dönen kodu girebileceğiniz anlaşılıyor .
#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));
}
Yukarıdaki örnek (Linux ile birlikte derlenip çalıştırılabilir gcc -O) yığın düzenine duyarlıdır.
EDIT: Alet zincirinize bağlı olarak, -zexecstackderleme bayrağını kullanmanız gerekebilir .
Hemen anlaşılmıyorsa, bu cevap esas olarak lols için yazılmıştır. Bunu okumaktan daha iyi veya daha kötü golf oynamaya ya da olumsuz psikolojik sonuçlara karşı sorumluluk almam.