TOP >> マニアックなプログラミング
トリッキーコードネット トリッキーなコード

【トリッキーなコード】Duff's device(ダフのデバイス)について (C言語)

Duffという人が考えた Duff's deviceという、有名なC言語のトリッキーコードがあります^^;)

それがこちらのコード↓↓

/* countは 「 必ずcount > 0 である」という前提 */ switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while ((count -= 8) > 0); }
do {} whileの中にcase文が入っていて、見るからに怪しさ満点のコードなのですが、 なんとビックリ、このコードはC言語の正当なコーディング手法なんだそうです! ( ゚Д゚)・・・ポカーン ※ 補足しておくと、case文とはただのラベルに過ぎず、ブロック中にあっても有効 (これをcaseラベルのfall-through特性というらしい)との事。 そして、上記コードは、以下のコードを最適化したものです。
do { *to = *from++; } while (--count > 0);
連続コピーを行うコードなのですが、 メモリマップされたデバイスの出力レジスタへのコピーの為、*toにインクリメントがつきません。 ループ展開することによって、処理を高速化しています。 ・・・ということで、早速テスト開始~♪
#include <stdio.h> #include <string.h> #include <malloc.h> int main(void) { char * psz1 = calloc(100, sizeof(char)); char * psz2 = "abcdefghijklmnopqrstuvwxyz"; char * to = psz1; char * from = psz2; int count = (int)strlen(from); do { *to++ = *from++; } while (--count > 0); // *to = NULL; puts(psz1); puts(psz2); }
文字列をコピーするテストコードです^^;) PCでテストする際は、*toにインクリメントをつけます。 また、callocではなくmallocでメモリ領域を割当てた場合は、最後に *to = NULLをするのを忘れないようにします。 実行結果は以下の通り Duff's deviceの実験結果1 そして、Duff's device風にコードを書き換えて実行してみます。
#include <stdio.h> #include <string.h> #include <malloc.h> int main(void) { char * psz1 = calloc(100, sizeof(char)); char * psz2 = "abcdefghijklmnopqrstuvwxyz"; char * to = psz1; char * from = psz2; int count = (int)strlen(from); switch (count % 8) { case 0: do { *to++ = *from++; case 7: *to++ = *from++; case 6: *to++ = *from++; case 5: *to++ = *from++; case 4: *to++ = *from++; case 3: *to++ = *from++; case 2: *to++ = *from++; case 1: *to++ = *from++; } while ((count -= 8) > 0); } puts(psz1); puts(psz2); }
実行結果は以下の通り Duff's deviceの実験結果1 最適化前のコードと同じ動作をしていることが、無事に確認できました~^^;) ちなみに、最適化前コードの以下の部分は、
int count = (int)strlen(from); do { *to++ = *from++; } while (--count > 0);
以下の様に書き直すことができます。
while (*to++ = *from++);
K&Rで推奨されている、strcpyのやり方です。
ひょっとしたら参考になるかもしれないページ : switchステートメント
トリッキーコードネット の TOPへ HOTNEWS の 総合TOPへ