2014/09/04

Recent entries from same category

  1. RapidJSON や simdjson よりも速いC言語から使えるJSONライブラリ「yyjson」
  2. コメントも扱える高機能な C++ 向け JSON パーサ「jsoncpp」
  3. C++ で flask ライクなウェブサーバ「clask」書いた。
  4. C++ 用 SQLite3 ORM 「sqlite_orm」が便利。
  5. zsh で PATH に相対パスを含んだ場合にコマンドが補完できないのは意図的かどうか。

コマンドラインから「あ*」等とワイルドカードを使用してコマンドを起動した場合、UNIX とは異なり Windows ではプロセス自身が引数を展開します(内部的にではありますが)。

main 関数の argc/argv は MSVC コンパイラであれば setargv.obj というオブジェクトファイルをリンクする事で展開される様になりますが、MinGW ではデフォルトでワイルドカード展開が実行されてしまいます。しかしながら、このワイルドカード展開は各コンパイラベンダーの実装次第という所があり、時に異なる挙動となる場合があります。

そこでワイルドカードは自前でプログラムで展開するのが一番良い訳ですが、MinGW の場合は既述の通り、デフォルトが展開動作となっています。しかし以下のたった1行のおまじないを入れる事で、引数展開が無効となります。

#include <stdio.h>

#define WIN32_LEAN_AND_MEAN  1
#include <windows.h>

int _CRT_glob = 0// おまじない

int
main(int argc, char **argv) {
  int i;
  printf("command line: %s\n", GetCommandLine());
  for (i = 0; i < argc; i++)
    printf( "argv[%d]: %s\n", i, argv[i]);
  return 0;
}

おまじないの行をコメントアウトした場合

C:\dev>a あ*
command line: a  あ*
argv[0]: a
argv[1]: あ.txt

おまじないを実行した場合

C:\dev>a あ*
command line: a  あ*
argv[0]: a
argv[1]: あ*

アドホックすぎてかなり嫌ですね。どのコンパイラでも同じ動作をさせたいのならば、GetCommandLineW()CommandLineToArgvW() を使うべきだと思います。

Posted at by | Edit