ใช้ lambdas (unportable)
แทน
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
) มีความไวต่อเค้าโครงสแต็ก
แก้ไข: ขึ้นอยู่กับ toolchain ของคุณคุณอาจต้องใช้การ-zexecstack
รวบรวมธง
หากไม่ชัดเจนในทันทีคำตอบนี้ถูกเขียนขึ้นสำหรับ lols เป็นส่วนใหญ่ ฉันไม่รับผิดชอบต่อการตีกอล์ฟที่ดีขึ้นหรือแย่ลงหรือผลลัพธ์ทางจิตวิทยาที่ไม่พึงประสงค์จากการอ่านนี้