C/C++でのevalの実現方法について

社内の古いC++のコードを改修しており,min_totalとかmax_totalみたいな似たような名前の変数に対して一括して,四則演算や関数を適用したくなった。 配列や構造体であればできなくはない。しかし,そうでなく単に変数名が似ている変数同士に対する一括処理はC/C++では難しい。 他のスクリプト系言語に存在するeval関数に相当することができれば,これは簡単に可能だ。 例えば,シェルスクリプトだと以下のようになる。 続きを読む
3

発端

. @senopen

C言語でevalやろうとしたら、マクロ使うしかないかな…やっぱり。連番とか似た名前の変数をまとめて処理したいことがけっこうある。 いや、最初から配列とか構造体とかにしておけという説はもちろんなんだけど。ねぇ…

2016-09-29 20:33:37

案1:自作

青子守歌 @aokomoriuta

自分で構文解析機とインタープリターを実装するだけだから簡単ですよ twitter.com/senopen/status…

2016-09-29 21:25:17
. @senopen

@aokomoriuta え?本当ですか? 完全に独立させていいなら電卓みたいにできるかもしれませんが。 geocities.jp/m_hiroi/linux/… 既存変数を維持したままをマクロ以外でできます?少なくとも簡単ではないのでは… スクリプト系言語なら,既存の変数でもできますが…

2016-09-29 22:35:29
青子守歌 @aokomoriuta

@senopen 今はありがたいことにフロントエンドはclangが使えるのでそれに喰わせて、あとはLLVMバックエンド作ればちょろいですね!!!!

2016-09-29 22:39:22
. @senopen

@aokomoriuta いや,それは全然ちょろくないのでは(苦笑) 不本意ですが,素直にマクロで片付けますかね… アレ(TeX)を想起させるマクロはできれば使いたくないのですけど,止むを得ません。

2016-09-29 22:46:54
青子守歌 @aokomoriuta

@senopen マクロを駆使しなければならないコードを必要とするならまず設計を見直す方が良い、さもなければ焼き捨てよ!

2016-09-29 22:56:46
. @senopen

@aokomoriuta いや,ごもっともです… ただ,ちょっとうまくやりたいだけなんですよね。そこだけでしか必要でありませんし,わざわざ設計をみなすまではしたくない… それか,その場しのぎとして諦めてベタ書きにしてしまいますかね… 後の保守性とか,きれいさとかなくなりますけど…

2016-09-29 23:14:06
青子守歌 @aokomoriuta

@senopen 逆にその場しのぎでいいならboost使えばそのへんの便利なマクロは一通りそろってますよ

2016-09-30 07:51:03
. @senopen

@aokomoriuta boost.preprocessorとかですか?boostは標準でないので、使えないことがあるのがネックです…。 頭に留めておいてまた調べてみます。

2016-09-30 08:50:09
青子守歌 @aokomoriuta

@senopen boostを「使えないことがあるレベル」と言うなら、標準ライブラリですら整備されていない処理系を想定してるってことですね。それは大変そう。

2016-09-30 08:53:35
. @senopen

@aokomoriuta #include <boost/boost.preprocessor>を書いたcppファイルを、昨晩自宅のUbuntu 16.04 g++ 5.4でコンパイルしたら見つかりませんとでたので、あることを前提にできないなと思いました。

2016-09-30 09:01:07
青子守歌 @aokomoriuta

@senopen ちなみにヘッダーは<boost/preprocessor.hpp>じゃないですか?

2016-09-30 09:04:10
. @senopen

@aokomoriuta たしかそうだったと思います。さっきは曖昧な記憶で書き間違えました。念のため今晩帰宅後再確認します。 古いコードを触っているので、新ライブラリ導入するのはなんか気が引けてしまいます。そこまでいくとやり過ぎかなと。 おとなしくベタガキで対処します…

2016-09-30 09:08:11
青子守歌 @aokomoriuta

@senopen まぁべた書きかせいぜいちょっとマクロ使うぐらいが無難でしょうねぇ・・・

2016-09-30 09:09:03
. @senopen

やっぱりUbuntu16.04標準ではboostライブラリはない。 そして,インストールしようとしたら,ビルドが必要で,ダウンロードしただけじゃだめ…やっぱり面倒だな。boostにはあまり頼らないほうがいいか。 boostjp.github.io/howtobuild.html @senopen

2016-10-01 15:12:18

案2:外部ファイルに出力

. @senopen

@pink_bangbi ありがとうございます。 しかし,これじゃない感が… C/C++でやろうとしたら,こんな感じの方法しかないのですかね… そもそもC/C++でevalやろうとする時点で負けですかね… 落ち着いたら時間をかけて方法を検討してみます。

2016-09-29 23:18:11
バンビちゃん@実際存在しません @pink_bangbi

@senopen そもそも eval() を使ってどのようなことをしたいのか、で手段が違ってくると思います。例えば連番の変数を定義したいのか、それとも動的に C++ のコードを実行できるようにしたいのか etc...

2016-09-29 23:25:07
. @senopen

@pink_bangbi イメージとしては, b_1=func(a_1); b_2=func(a_2); b_3=func(a_3); みたいな感じです。連番や似たような名前の変数を処理したいだけです。

2016-09-29 23:27:06
バンビちゃん@実際存在しません @pink_bangbi

@senopen で、あれば eval() みたいなものではなくてマクロを使うのが C/C++ に置いてベターだと思います。

2016-09-29 23:28:21
. @senopen

@pink_bangbi まあ,そうなりますよね… シェルスクリプトだと, for i in 1 2 3 do eval "b_$i=func(a_$i)" done で簡単にできるので,こんな感じでC/C++でもやる方法ないかなと思った次第でした。どうもありがとうございました。

2016-09-29 23:30:49

案3:Boost.Preprocessor

1 ・・ 4 次へ