C (90) (79) (59) (47) (42) (40)
静的な整数
x=1;a(){char b[8];printf("%d\n",x++);b[24]-=5*(1-x/101);}main(){a();return 0;}
関数 05
番号を出力するものは、それ自体を呼び出しません!バッファ オーバーフローを悪用し、リターン アドレスを変更して、プログラム カウンタが function 14
を超えるようにしました。 必要な限り、もう一度。
これが再帰と見なされるかどうかはわかりませんが、試してみる価値があると思いました。> 、少し違うかもしれません。
Exp1: スタック 39
にダミー バッファを割り当てました 、次に、リターン アドレスの場所である、通過した場所をアドレス指定します。関数 45
の逆アセンブルから、バッファの開始と戻りアドレスの場所の間の距離を予想しました .
Exp2: 式 59
、 61
です すべての 74
に対して そして 80
94
の場合 . 101
の逆アセンブルを見ることで (私の場合)リターンアドレスを5つ減らすと、PCは112
の呼び出し元に設定されます また。更新されたコードでは、127
の戻り値 ループ状態のチェックに使用されます。
更新: ugoren の提案とその他の変更を適用した後:
x;a(){int b[2];b[3*(printf("%d\n",++x)&2)]-=5;}main(){a();}
アップデート 2: 関数 135
を削除した後 :
x;main(){int b[2];b[6^printf("%d ",++x)&4]-=7;}
アップデート 3:
x;main(b){(&b)[1|printf("%d ",++x)&2]-=7;}
アップデート 4: mbz に感謝します :)
x;main(b){(&b)[3|printf("%d ",++x)]-=7;}
85
C (gcc)
#define c printf("%d ",i++);
#define b c c c c c
#define a b b b b b
main(i){a a a a}
コマンド ライン引数が渡されなかったと仮定します。
C++ (159 136)
テンプレート付き。
#include<cstdio>
#define Z(A,B,C,D)template<A>struct P B{P(){C;printf("%d ",D);}};
Z(int N,,P<N-1>(),N)Z(,<1>,0,1)int main(){P<100>();}