パスワードを忘れた? アカウント作成
899771 story
プログラミング

わかりにくいCプログラム作成を競う「IOCCC」が5年ぶりに開催 57

ストーリー by kazekiri
難読 部門より
あるAnonymous Coward 曰く、

あのオブファスケが帰ってきたそうだ。どれだけ「わかりにくい」Cプログラムを作成できるかを競うコンテスト IOCCC (International Obfuscated C Code Contest)が5年ぶりに開催される (マイナビ)。自然体で普通にコード書くとオブファスケなみんな! それ行け、出番だ!

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by Anonymous Coward on 2011年11月19日 12時12分 (#2053051)

    過去の受賞作品 [ioccc.org]を見ると、第1回の作品ですでに相当難解です。
    このへんに解説を見つけたけど [hatena.ne.jp]。

    • by Anonymous Coward

      理解に必要な知識量と方法論は人それぞれなのに対して、
      理解出来ない状態は万人共通だからでしょう。

    • by Anonymous Coward
      一般レベルでは、再帰呼び出しや三項演算子は意見が分かれるところではないかと。
      • by Anonymous Coward

        再帰呼び出しや三項演算子をうまく使えば、繰り返しや条件判断も表現できるから、
        任意のプログラム全体を1つの式で表現できないでしょうか。
        つまり、セミコロン使用禁止とか。
        ついでにカンマ演算子も使用禁止にできるかな。

        • by Anonymous Coward

          任意のプログラム全体を1つの式で表現できないでしょうか。

          Lisp でも使ってろよ。いや、使ってください。使いましょう。

      • by Anonymous Coward

        三項演算子はコーディング規約で使用禁止にしてる所なんかも事もあって、若い開発者は解読不能だったりするんですよね。
        わかりにくいというよりも、(使う機会が無いから)存在すら知らないor忘れてるという。

        • by Anonymous Coward

          日常的にエクセルを使って、セルに条件判断式を入力したりする人のほうが、三項演算子になじみやすいかもね。

    • by Anonymous Coward

      Subjectを本文の一行目として使用するのは最高にわかりにくい

  • 中途半端に実装されたオリジナルインタプリタが、コード中にハードコーディングされたオリジナルバイナリデータを逐次解釈しながら実行するってプログラムだった。やってることが単純な割に大量のコードが書き散らされていて、中には一度も実行されない処理も多数で、何が何だかさっぱりだったよ。作った当人は「バイナリデータを変更すればプログラムの動作を変更できるから、仕様変更にも強いし、柔軟性も高い。俺様凄い」と思って作ったらしい。条件分岐するうまい方法を思いつかなかったらしく、実行中にバイナリデータを書き換えたりするという・・・。

    • そういうソフトをいただいた事もありますが、一応メリットはあるんですけどね。
      仕様との合致を確認しやすいとか、簡単な仕様変更には対応しやすいとか。

      一方でデメリットはインタプリタ部分の変更が必要となる場合に泣きが入ることですか。
      非対応の入力が増えるとが、オペコード部分のビット数が足りなくなったとか。
      オリジナルを作った人はいいんです。最初は小さいのを作ってこつこつ増設ですから。
      でも引き継いだ人はすでに建て増し済みの温泉旅館を受け取るので何が何だか分からないという。

      まぁ条件次第ですが、それほど悪い考えじゃないと思いますよ。

      でも、バイナリコードの書き換えは反則です。

      親コメント
    • by Anonymous Coward

      じつはそのバイナリデータとはZ80のコードだったとか。
      あるいは、マイクロプロセッサを作る仕事したくて挫折した人が、
      俺仕様のマイクロプロセッサを作った気分になりたくてやったとか。

      どちらにせよ迷惑に違いないことには合意。
      せめてそのオリジナルバイナリデータを作成するためのアセンブラなり
      コンパイラを用意してもらわないと。(そういう問題ではない)

  • by Anonymous Coward on 2011年11月18日 19時40分 (#2052747)

    C言語AA大会やないか

  • by Anonymous Coward on 2011年11月18日 20時05分 (#2052753)

    http://codepad.org/Nn0TbhNk [codepad.org]

    # 解り辛い挙動、ではないのか。

  • by Anonymous Coward on 2011年11月18日 20時17分 (#2052755)

    #define FALSE -1

    • #define BEGIN {
      #define END ;}
      親コメント
      • by Anonymous Coward

        オイオイV7 UNIXの真似をして優勝はないだろう?
        http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h [tuhs.org]

        • by Anonymous Coward

          > V7 UNIXの真似

          せっかくcまでこれたものを、アセンブラに戻してどうする
          しかし、これわかりやすいかも MASMみたいでなついよ

        • by Anonymous Coward

          Pascalかも。

          • by Anonymous Coward

            ALGOL です(ALGOL 68 だったかな)。

            というか、IOCCC 開催のきっかけとなったのが、そのマクロを用いて書かれた Bourne Shell のソースコードなわけですが、ここスラドにおいてももはや UNIX 文化はコモンセンスではないのですね。

            IOCCC FAQ [ioccc.org] からの引用:

            Q: How did the IOCCC get started?
            A: One day (23 March 1984 to be exact), back Larry Bassel and I (Landon Curt Noll) were working for National Semiconductor's Genix porting group, we were both in our offices trying to fix some very broken code. Larry had been trying to fix a bug

      • by Anonymous Coward

        どうせなら、逆に定義しろ

      • by Anonymous Coward

        プリプロセッサ系は卑怯な気がするなぁ。
        #define car <st
        #define id .h>

        で、

        #include cardioid
        #include carringid

        とかやられたら、誰にも読めない。

        • by fcp (32783) on 2011年11月19日 0時10分 (#2052893) ホームページ 日記

          「プリプロセッサ系は卑怯」なんてことは全然ありませんが、審査するのは人間ですから、ありきたりな手を使っても良い評価は得られません。実際、ガイドライン [ioccc.org]の Our Likes and Dislikes の節に

          Doing masses of #defines to obscure the source has become 'old'.

          と書いてある通り、マクロを使って読みにくくしていることしか見るべきところがないようなエントリーは古臭いというのが評価基準です。

          ちなみに、 #2052882 [srad.jp] の人も書いている通り、 #2052871 のコードはコンパイルエラーだと思いますけど……。マクロ展開は字句解析の後で起こるので、 car というマクロが定義されていても cardioid というトークンには影響を与えません。 (なんてのは当たり前過ぎる話なので、何か引っかけがあるのかと思いますが、わかりません。)

          親コメント
          • by Anonymous Coward

            プリプロセッサを手動で反復適用するとかすれば、あるいは。
            ああ、でも、n 回目のプリプロセスのためのディレクティブが n - 1 回まではエスケープされるように書かなきゃならなくなるのか。

        • by Anonymous Coward

          あなたの望むようには展開されない

      • by Anonymous Coward

        真面目にやってこそアレゲ [pro.or.jp]
        たとえ本人にその意志がなかったとしても

    • by racco (37699) on 2011年11月19日 7時54分 (#2052966)
      おまえらなんで、新しいアイディアをださないんだよ もうとっくの昔にやられてるよ コードを書くコードを書くコードを書くコードを書くコードを書くコードを書くコードを書くコードを書くコードを書くコードを書くコード とか
      親コメント
      • by Anonymous Coward

        もう「CとしてもFortran 77としてもシェルスクリプトとしても正しいプログラム」とか「シェルスクリプトとして実行すると自分自身をMakefileとして自分自身をコンパイルするプログラム」はあるよねw

        • by ruto (17678) on 2011年11月19日 12時44分 (#2053070) 日記

          言語1のプログラムが言語2のプログラムを出力して、言語2のプログラムが言語3のプログラムを出力して、言語3のプログラムが最初の言語1のプログラムを出力するというような循環的な自己出力プログラムは一般化されています [sigfpe.com]。

          Fnxyは言語xで書かれたプログラム(関数)であるとする。
          Fnxyはn個の文字列G1, ..., Gnを引数として取り、言語yによるプログラムYを出力する。
          Yはn個の文字列G2, G3, ..., Gn, G1に対して言語yで書かれた関数G2を適用するものであるとする。

          このとき、言語xによるプログラムF3xy(F3xy, F3yz, F3zx)は言語yによるプログラムF3yz(F3yz, F3zx, F3xy)を出力する。
          F3yz(F3yz, F3zx, F3xy)はF3zx(F3zx, F3xy, F3yz)を出力し、F3zx(F3zx, F3xy, F3yz)はF3xy(F3xy, F3yz, F3zx)を出力するので元に戻る。

          これを応用して、各言語での関数定義の構文などを定義すると、循環的な自己出力プログラムを出力するプログラム [sigfpe.com]が書けます。

          親コメント
        • by greentea (17971) on 2011年11月19日 14時02分 (#2053108) 日記

          //から始まる形式のコメントを使っていいのなら、コンパイラがShift_JISに対応しているか否かで挙動が変わるプログラムが書ける……ってのも、既出?

          --
          1を聞いて0を知れ!
          親コメント
        • by Anonymous Coward

          マシン語で、エントリポイントを変えると別のプログラムになる、ってのが昔あったような。
          オペコードとオペランドが交互に並んでいて、それを逆に解釈するみたいなイメージ。

  • by Anonymous Coward on 2011年11月18日 20時31分 (#2052761)

    俺の三重ポインタが火を噴く時が来たようだな……

    #引き継いだソースにあってキレそうになった

    • 良く"ポインタのポインタ"で混乱している人がいるけど
      typedef 使えば理解もコーディングも楽になりますよ.

      こんな感じです.

      typedef int T;
      typedef T* PT; // "int" のポインタ
      typedef PT* PPT; // "intのポインタ" のポインタ
      typedef PPT* PPPT; // "intのポインタのポインタ" のポインタ

      変数宣言時はこんな感じ

              T t = 1;
              PT pt = &t;
              PPT ppt = &pt;
              PPPT pppt = &ppt;

      関数の引数で3重ポインタ(?)を使う場合はこんな感じ.

      void hogehoge( PPPT *pppt)
      {
            PPT ppt = ....;
              *pppt = &ppt;
      }

      これなら,次に引継いだ人もキレないでしょう.

      親コメント
      • by Anonymous Coward

        「P」を「*」と脳内変換しながら読まないといけない分だけ、よけいに分かりにくくなっています。

        • by Anonymous Coward

          確かに意味がないですよね。どうせなら、

          typedef int T;
          typedef T* PT; // "int" のポインタ
          typedef PT* ARR_PT; // "intのポインタ" の配列
          typedef ARR_PT* ARR_ARR_PT; // "intのポインタの配列" の配列

          とやってもらった方が、配列の先頭のポインタなのか、要素のポインタなのかが判別しやすい。前者ならARR_ARR_PT、後者ならARR_PT*と宣言することで、一目瞭然。

      • by Anonymous Coward

        多重ポインタって、指す先がポインタなのか(多次元)配列なのか、メモリ確保状況はどうなっているのかが
        管理しきれなくなってくるというのが混乱の元だと思います。
        そういう区別をtypedefを使ってうまく表現すれば、読みやすさに大きく貢献しますね。

        Cのポインタの表記法そのものは(多重になっても)単純明快でややこしくないし、仮に*の数を間違っても
        コンパイラが指摘してくれるから、あまり問題ではないと思います。

        # 10重とか100重くらいになると*の並びを読むだけで目がくらむでしょうけど。
        # 数千重くらいになると画面全体が「*」で埋め尽くされて、画面をスクロールしても分からない
        # なんてことになりそう。
        # どういうところに10重とか100重とか数千重のポインタを使うと効果的なのか、見当もつかないけど。

        • そうそう。
          void sub( int *a) とかみたとき、
          配列として使うためにポインタになってるか
          アドレス渡しで値を取り出すためのポインタなのか、
          意図がわからないと判断つかない。

          • by Anonymous Coward

            配列として使うのであればサイズを渡すべきとは思いますけどね。
            何度も修正した結果、当初の想定から外れて
            配列の範囲外アクセスとかありえますから。

            サイズを渡せば疎結合になりますし。

        • by Anonymous Coward

          Cの学習初期にポインタと配列が同じようなものだと覚えた人が、
          多次元配列とポインタの相性の悪さを受け入れられなくて挫折するみたいな感じじゃないでしょうか。

    • by Anonymous Coward on 2011年11月18日 22時22分 (#2052817)

      つ津

      親コメント
    • by Anonymous Coward on 2011年11月18日 22時37分 (#2052827)

      3重ポインタ使いはポインタの魔術師と呼ばれていた
      他に、マクロを多用するマクラーレンと呼ばれる奴もいた

      親コメント
      • by Anonymous Coward

        魔術師なら「関数の配列へのポインタを返す関数へのポインタの配列へのポインタ」くらいは使ってみたりするのでしょうか。
        私には無理だけど。

    • by wolf03 (39616) on 2011年11月19日 2時14分 (#2052936) 日記
      8次元程度の配列とどっちが嫌ですか?
      親コメント
    • by Anonymous Coward

      古いコードでは文字列の配列だけで二重(?)で、さらに可変長で…

    • by Anonymous Coward

      何重のポインタを作ったところで、ややこしくなっていくのは確かですが、アイディアとしては同じだと思うのです。

      可変重ポインタとかって、できないでしょうか。

      void hogehoge(int n)
      {
      double (*)na;
      :
      :
      }

      みたいな。実現方法も分からないし、実現したところで有効な使い方があるのかどうかも分からないけど。

      • by Anonymous Coward

        上の議論とかもまとめてそうだけれど、型の検証がほしいから何重だろうがきちんと宣言するのであって、それが面倒だというなら void * にして、リファデリファの局面でキャストすればいいだけじゃん。

  • by Anonymous Coward on 2011年11月19日 9時48分 (#2052994)

    古典的だけど、

    int* a,b;

    とか。

typodupeerror

目玉の数さえ十分あれば、どんなバグも深刻ではない -- Eric Raymond

読み込み中...