えいあーるれいの技術日記

ROS2やM5 Stack、Ubuntuについて書いています

さすがにshebangを2行目に書こうなんて人いないよね??(煽り

夕食を食べてる途中に思いついたC++bash実行アルゴリズム

「絶対コンパイルされない記述の中にインストール用スクリプト入れたら1つのファイルで完結するんじゃね??」

↑これを実装してTwitterに載せたところ、結構伸びました。


一方で、「shebangつけたほうがいい」などの意味不明なコメントも見られ、非常に頭にきたので本来は記事化する予定はなかったですが、記事にします。


再現コード

私が実行に使用したコードはこちらになります。(example.cpp)

#if NULL
THISFILE=`basename $0`
NAME=`basename $0 .cpp`

g++ -o $NAME $THISFILE
./$NAME
rm $NAME

exit
#endif

#include <stdio.h>

int main()
{
    printf("hello world\n");
}

このプログラムは非常にシンプルなHelloWorldのプログラムであり、普通は以下のように実行します。

g++ example.cpp -o example
./example

これをbashで解釈される性質を利用(悪用)して「実行可能な」C++ファイルを作成したわけです。

利用したのは#if NULL(0でも可)によるコンパイラからの除外です。


#if ~ #endif は条件付きコンパイルで、(マクロ含む)コンパイル不要な条件式の結果が真である場合にコンパイル対象に入れることができます。

そもそも定義されているかどうかによって分岐する #ifdef #ifndefなどもあり、プラットフォームやOSなどに応じて使い分けます。


このプログラムはbashで実行した際に次のように遷移していきます。

  1. #if NULL : コメントとして無視されます(C++では #endif まで無視されます。)
  2. THISFILE='basename $0' : 自分のファイル名 example.cpp を取得します(バッククォートを'に変えています)
  3. NAME=basename $0 .cpp` : .cppを取り除きます
  4. g++ -o $NAME $THISFILE : コンパイルします。 -o オプションで後ろに $NAMEexampleに置換)というバイナリを生成します。
  5. ./$NAME バイナリ ./$NAME を実行します。
  6. rm $NAME バイナリ $NAME を削除します。
  7. exit bashファイルとしての処理が終了します。
  8. #endif : 以降、C++ファイルが続きます。


この記法は # を無視するスクリプト言語の仕様と #if ~ #end によるコンパイル除外が可能なCの仕様を組み合わせてあたかもコンパイルなしで ./a.out ができる マジック のような

「懐かしい」と「面白い」を狙った投稿でした。


しかし、一部のプログラマセンスを疑うようなコメントがきて非常に腹が立ったので、ここで煽ろうと思います。

どんな投稿なのかはぜひ、上の伸びたツイートの引用RTをご覧ください。


指摘するならここだぞポイント

なぜ 「shebang を付けろ」がプログラマセンスを疑うような投稿であるかを以下に示します。

  1. C/C++の構造上、shebangが使えない
  2. .cpp の拡張子でbash実行ができるようなファイルは拡張子の意味がない。(←ネタであることが理解できていない、読解力不足)
  3. どうしてもbashで実行したいなら bash example.cpp でいいじゃん。shebangよりも明示的じゃない。


1は 1行目に #if NULL と競合するのでどう考えても無理です(C/C++側がコンパイルするため)。仮にできるなら教えてほしい。弟子にしてください。

2、3は言うまでもないでしょう。読みやすくするなら言語を混ぜていいわけがないですよね???

以上より、指摘するなら

「なにが実行可能なC++だよwwwww結局内部でbash動かしてコンパイルしてるだけじゃん」

です。shebangつけろコメントをした人は反省しなさい。


補足:shebangは2行目に書くと意味ない

macで実験しました。

maczshのターミナルですが、少なくとも私の環境では自動的にbashで実行されるようです。

↓これなら大丈夫


本当に変に伸びたツイートには必ずと言っていいほどクソリプがつくので相手にするのが面倒です。

…自戒の念も込めて。