2014年06月10日

文字列定数


Lua スクリプトなり HLSL なり、短いコードを外部ファイルに依存せずに動かしたい時には

 const char *lua_script = "function add(a, b) return a+b; end; function sub(a, b) return a-b; end";

などと書くわけですが、これだと見にくいので無理やり改行して

 const char *script = " \
  function add(a, b) return a+b; end \
  function sub(a, b) return a-b; end \
 ";

とかやっていたのですが、行の最後をエスケープするのて結構面倒なんですよね。

そこで、最近になって知ったのは #define STR(x) #x を使う方法です。
define の引数を使うときに # をつけると、引数がそのまま引用符でくくられるのですが(assert の警告文とかで使われてますよね)
これをうまく使ってやろうというやつです。つまり

 #define STR(x) #x
 const char *script = STR(
  function add(a, b) return a+b; end
  function sub(a, b) return a-b; end
 );

と書いてやれば、たとえ式の途中で改行していても問題なく引用符の中に入り、文字列定数になるというわけです。便利ですね。
もっと早くに知っていれば...

ちなみに

 #define STR(x) #x
 const char *script = STR(
  function add(a, b) return a+b; end // コメント
  function sub(a, b) return a-b; end // コメント
 );

のように定数内部にコメントを書いた場合、このコメント部分は文字列定数には入りません。しかし、

 #define STR(x) #x
 const char *script = STR(
 #if 1
  function add(a, b) return a+b; end
  function sub(a, b) return a-b; end
 #endif
 );

のようにプリプロセッサ命令を書いた場合は、文字列定数にもそのまま含まれています。
この動作がコンパイラ依存かどうかはわかりませんが、少なくとも MSVC ではそうなってました。

また、ソース上での改行文字はすべて無視されます。全部つながった1行の文字列定数として扱われるため、
HLSLのように改行が関係ないコードだったらよいのですが、lua のように改行が命令の区切りになっている言語では注意が必要です。

Lua の場合、正しく動かすためには改行文字を文字列定数にきちんと含めるか、

 #define STR(x) #x
 const char *script = STR(
  function add(a, b) return a+b; end \n
  function sub(a, b) return a-b; end \n
 );

常に ; をつけて命令の区切りを明示する必要があります

 #define STR(x) #x
 const char *script = STR(
  function add(a, b) return a+b; end;
  function sub(a, b) return a-b; end;
 );

posted by JUNOSOFT at 08:44| Comment(0) | プログラミング

2014年06月06日

GLFW

GLUT にはよくお世話になっているのですが、ウィンドウを閉じても閉じきらなかったり(?)、
マルチウィンドウ非対応とか、ウィンドウハンドルを取得する関数がないとか、不満もいくつかありました。

もう何年もメンテナンスされてないし、これ以上の進化は望めそうにありません。
GLUT の後継ぽくなっている freeglut でもいいんですが、もう少し素直に使えるやつがないかなーと思っていたら、GLFW というものがあるみたいですね。
マルチウィンドウにも対応しているし、ウィンドウハンドルもとれるぽいし、さらに GLUTと違ってウィンドウにポインタを一つ保持させることができるので、
クラスと組み合わせて使うとが簡単にできそうです。次からはこれでテストプログラムを書いてみようと思います。

http://www.glfw.org/docs/latest/index.html
posted by JUNOSOFT at 00:01| Comment(0) | プログラミング