IOCCC2012 供養 / C と C++ を見分けるプログラム

入賞できないだろうなーと思ってたけどやはりできなかったボツネタ。

       #include                                                    <iso646.h>
    #include/*C*/                                                  <stdbool.h>
   #include/*C++?                                                  !*/<stdio.h>
  struct/**/t{int            s[2                    ];}            ;int s,i;int
 #define       C(            a/*                    */,                  b)a##b
#define                      W(a                    )S(                  /**/a)
#define                      f(x                    ,y)                  for(i\
=-1;19                       >++                    i;)                 putcha\
r(i>17                       ?10                    :i>                4?(y-2\
?i%6==                       3+(                    4&+               sizeof\
(x)):i                %6&&+sizeof(x)>2)      ?'+':32:(y%3/2&&i        <4)^(\
y&1)^!                (i%4)?32:'C');i=2      [W(__cplusplus)"C        C++"];
main()                {struct/*C++?*/s{      C(str,uct)t{int(s        );}t;
#define                      S(a                    )#a
int(s);                      };f                    (s,
 0)f('C'       ,1            )f(                    W(C               (x,or
  )),2);;f(struct            t,3                    )f(               true,
  4)i=i*1//*1*/(0            ["c                    "]/               +'+')
    ;return(i>89?            0*C                    (p,               rintf
      )("%d\n",i             ):0                    );}               /*C*/

__cplusplus マクロ以外に C と C++ で挙動を変える方法は結構あって、 5+2 種類集めて、 C/C++ とあと C99 コメントの扱いがどうなってるかを表示する、というプログラム。実行例:

> gcc -ansi prog.c
> ./a.out
 CCC
C   C
C
C   C
 CCC
> gcc -std=c99 prog.c
> ./a.out
 CCC
C   C
C
C   C
 CCC
99
> g++ prog.c
> ./a.out
 CCC     +     +
C   C    +     +
C    + +++++ +++++
C   C    +     +
 CCC     +     +

メインの出力部分は5行あるんだけど、5行別々に判定しているので、中途半端なコンパイラとかがもしあればどっちとも言えない出力になる、と思います。

7種類をわかりやく説明したもの。 W(C(x,or)) は W(xor) で良かったんじゃないのなんでかな…

    #include <iso646.h>
    #include <stdbool.h>
    #include <stdio.h>
    
    const char c[] = "C++";
    int s;
    struct t { int s[3];};
    
    #define C(a,b) a##b
    #define S(a) #a
    #define W(a) S(a)
    
    int main() {
      unsigned i;
      struct s { int s[3]; struct t { int s[1]; } t; };
    
      for (i = 0; i < 7/-~sizeof('C'); i++) putchar(c[i]);
      puts("");
    
      for (i = 0; i < sizeof(s) / sizeof(int); i++) putchar(c[i]);
      puts("");
    
      for (i = 0; i < sizeof(struct t) / sizeof(int); i++) putchar(c[i]);
      puts("");
    
      for (i = 0; i < 6/-~sizeof(true); i++) putchar(c[i]);
      puts("");
    
      for (i = 0; W(C(x,or))[i]; i++) putchar(c[i]);
      puts("");
    
      for (i = 0; i < 3 - sizeof(W(__cplusplus)) / 5; i++) putchar(c[i]);
      puts("");

      for (i = 0; i < 3 //**/ 3
             ; i++) putchar(c[i]);
      puts("");
    
      return 0;
    }

まー地味すぎるし、そもそも上記7種類がわりとどうでもいいんだよな…こういうの自分的には好みではあるんだけど。次があるならもう少しなんか頑張ろうと思います。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h