ページ 11

[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 14:09
by kaiten
実力も顧みずに作ってみたので黒歴史覚悟で晒してみようということで。

内容はC++のswitch構文の真似事をするマクロです。
本家switch文だとcaseで定数しか指定できなかったり範囲指定ができなかったりでたまに不便なので作ってみた次第です。

友人に頼んで試用したりしてもらってるのですが、公開する前に皆さまに改善点やバグなどをあげていただきたいのです。
仕様などはreadmeに書いたつもりですが不足がありましたら教えてください。

zipデータ
http://dixq.net/zip/bbs/kaiten_0.zip

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 14:47
by 組木紙織
なんだか面白そうですね。
まだ何も見させてもらっていませんが、
2つ疑問点があります。
1:
redmeに 学校提出などで使う場合は事前に連絡ください。
とあるのですが、もし使う場合はどこへ連絡をすればよいのでしょうか?

2:
最新バージョンはどれですか?

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 14:51
by kaiten
あ…本当ですね……
1に関しては完全にミスです。メールアドレス載せたつもりが載ってないですねこれ。
2に関しても私の不手際でした。~Typeとなっているのは亜種みたいなものなので正式な最新版はver0.214となります。
編集しておきます。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 14:56
by たかぎ
こういうのはなかなか実用にはなりにくいのですが、個人的には好きです。

一応、ざっと見た範囲での問題点を指摘しておきます。

1. RUNというマクロ名は分かりにくいので、FALL_THROUGH(またはFALL、またはTHROUGH)の方がよいのでは?
2. S_ENDを忘れやすい。whileの代わりにforを使えばこれはなくせるはず。
3. SWITCHブロック内で例外が送出されると、Switch_sysがリークする。
4. SWITCHブロック内でcontinueを使うと永久ループになる(while → forで解消可能)。
5. SWITCHマクロで、型名とオブジェクト名を , で区切るのがちょっと不細工(下記で詳述)

SWITCH(int, x)ではなくSWITCH(x)で済むようにはなりませんか?
例えば、xを参照渡しする関数テンプレートを作って、その中でSWITCH_sysを生成するとか。
SWITCH_sys::conditionの扱いがやや面倒ですが、解決方法はあると思います。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 15:11
by kaiten
たかぎさん、ご指摘ありがとうございます。
RUNは確かに解り辛いですね。FALLに変えさせていただきます。
例外によるリークは全く考えていませんでした。例外処理を使ったことがなかったので…対策考えてみます。
5なんかは私も不満のある部分でした。どうしようもないと思ってあきらめていたのですがこれも考えてみます。

それで、2と4に関して質問させてください。
バージョンは0.214で話させていただきます。
まず2の方なのですが、S_ENDはbreak処理だけでなくdelete処理や上のCASEのスコープを終了させる役目も担っているのですが、それでもなくすことは可能なのでしょうか?
続いて4なのですが、そもそもブロック内でcontinueを使う場合と言うのはどのような場合なのでしょうか?また、C_REFINEマクロではcontinueを使っているのですが、これについてはどのように対処すればよいのでしょうか?

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 15:42
by たかぎ
> まず2の方なのですが、S_ENDはbreak処理だけでなくdelete処理や上のCASEのスコープを終了させる役目も担っているのですが、それでもなくすことは可能なのでしょうか?

まず、breakとdeleteをなくすには、こんな感じでどうでしょうか?
#define SWITCH_SYS(type, condition) \
  for (std::auto_ptr<SWITCH_sys<type> > Switch_sys(new SWITCH_sys<type>(condition)); \
       Switch_sys.get() != 0; \
       Switch_sys.reset()) {
CASEのブロックを閉じるのはやや面倒ですが、SWITCHブロックの末尾のブロックと対応させるようにすればどうにかなるはずです。
例えば、
#define CASE_SYS(pattern) \
  } \
    if(Switch_sys->Plus_condition_goto(), \
       (pattern==Switch_sys->Get_condition())|| \
       (Switch_sys->Get_condition_goto()==Switch_sys->Get_goto_target())) \
    Switch_sys->Set_condition_default(false); {
こんな感じでしょうか? (検証していないので、細部は違っているかもしれません)

> 続いて4なのですが、そもそもブロック内でcontinueを使う場合と言うのはどのような場合なのでしょうか?

例えば、
for (;;)
{
  std::cout << "1: グー, 2: チョキ, 3: パー" << std::endl;
  std::cint >> x;
  switch (x)
  {
  case 1:
  case 2:
  case 3:
    // 勝敗判定
    break;
  default:
    continue;
  }
}
のような場合です。
どんな使い方をするかはクライアントコードまかせですので、用途を制限するのは問題があります。

> また、C_REFINEマクロではcontinueを使っているのですが、これについてはどのように対処すればよいのでしょうか?

forの第三節で、問答無用でdeleteするのではなく、何らかのフラグをもうけてはどうでしょうか?

> 5なんかは私も不満のある部分でした。どうしようもないと思ってあきらめていたのですがこれも考えてみます。

例えばこんな感じでしょうか?
template <typename T>
inline SWITCH_sys_base* SWITCH_sys_builder(T& x)
{
  return new Switch_sys<T>(x);
}
生のnewを使うのではなく、このように一枚かぶせれば型ディスパッチが可能になります。
Get_conditionなどをどうすべきか、一工夫いりそうですが...

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月12日(月) 15:47
by たかぎ
{ の位置を間違いました。
#define CASE_SYS(pattern) \

  } \
    if(Switch_sys->Plus_condition_goto(), \
       (pattern==Switch_sys->Get_condition())|| \
       (Switch_sys->Get_condition_goto()==Switch_sys->Get_goto_target())) \
    { Switch_sys->Set_condition_default(false);
こんな感じです。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月13日(火) 20:21
by kaiten
遅くなってしまいました。すみません。

たかぎさんの案を参考に組み替えていて思ったのですが、continueによる無限ループを回避したとしても、for文やwhile文を使っている以上ユーザー側の意図した動作にはならないのではないでしょうか?対策自体は考えたのですが、これについての見解をお聞きしたく思います。

あと、newについての工夫はこれ、デザインパターンの工場メソッドというものでしょうか?なんか昔チラと見たものに似ていた気がしましたので。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月13日(火) 20:52
by hoge
そもそも、SWITCH_sysを動的に確保する理由がよく分からない。
#define SWITCH_SYS(type, condition) \
 { \
 typedef type type2; \
 SWITCH_sys<type2> Switch_sys(condition); \
 while(true){
じゃ、ダメなの?

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月13日(火) 21:36
by kaiten
>hogeさん
確かにそうですね。わざわざ動的に確保している理由が見当たらない……
製作自体はだいぶ前から始めてるんで以前は意味があったのか……たぶん考え過ぎたんだと思います。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月13日(火) 21:51
by たかぎ
> たかぎさんの案を参考に組み替えていて思ったのですが、continueによる無限ループを回避したとしても、for文やwhile文を使っている以上ユーザー側の意図した動作にはならないのではないでしょうか?対策自体は考えたのですが、これについての見解をお聞きしたく思います。

そうですね。
無限ループを回避できるだけです。
もうちょっと考えればよい方法が見つかるかもしれません。

といっても、continueがきかないループとなると、gotoかsetjmp/longjmp以外には思いつきませんが...
gotoはともかく、setjmp/longjmpは重過ぎますね。

Re:[雑談?]自作ヘッダを公開してみる

Posted: 2009年1月17日(土) 00:59
by kaiten
しばらく製作ができそうもない状況なので一旦解決にしておきます。雑談に解決というのもおかしな話かもしれませんがw

皆さまありがとうございました。もっと形になったらまた持ってこようかと思います。