- 2008/12/10 19:04
- C/C++
devkit/plug-insの中あさってて、quadricShape.cppの中からこんなものを発見。
#define MAKE_NUMERIC_ATTR( NAME, SHORTNAME, TYPE, DEFAULT, KEYABLE )
MStatus NAME##_stat;
MFnNumericAttribute NAME##_fn;
NAME = NAME##_fn.create( #NAME, SHORTNAME, TYPE, DEFAULT );
MCHECKERROR(NAME##_stat, "numeric attr create error");
NAME##_fn.setHidden( !KEYABLE );
NAME##_fn.setKeyable( KEYABLE );
NAME##_fn.setInternal( true );
NAME##_stat = addAttribute( NAME );
MCHECKERROR(NAME##_stat, "addAttribute error");
これ自体は明らかにマクロなんですが、##ってなんだ?
関数マクロのルールとかなんかそういうやつなんですかね。
なんでこのマクロに興味を持ったかというと、これです。↓
MAKE_NUMERIC_ATTR( radius1, "r1", MFnNumericData::kDouble, 1.0, true );
MAKE_NUMERIC_ATTR( radius2, "r2", MFnNumericData::kDouble, 1.0, true );
MAKE_NUMERIC_ATTR( height, "ht", MFnNumericData::kDouble, 2.0, true );
MAKE_NUMERIC_ATTR( startAngle, "sta", MFnNumericData::kDouble, 0.0, true );
MAKE_NUMERIC_ATTR( sweepAngle, "swa", MFnNumericData::kDouble, 90.0, true );
MAKE_NUMERIC_ATTR( slices, "sl", MFnNumericData::kShort, 8, true );
MAKE_NUMERIC_ATTR( loops, "lp", MFnNumericData::kShort, 6, true );
MAKE_NUMERIC_ATTR( stacks, "sk", MFnNumericData::kShort, 4, true );
そうそうそうそう!こういう感じでアトリビュートの宣言したかったんですよ!!
なんでこう毎度毎度面倒臭い記述をせねばいかんのだ、、と思ってたので、少しでも短くなるのは非常に嬉しい限り。
少しでも楽するために、ちょっとこの辺調べてみます。
関数マクロってホントはinline関数使えよ、非推奨だよ、ってモノらしいという話も聞いたことがあるので、
果たしてどの程度使っていいものなんだ、、と若干おっかなびっくりではありますが、
まぁ、失敗して覚えられたらそれでOKだし、このまま使えるならもっとOKwwwwwwwwwwwwww
とりあえず、調べてみよう。
———————————————————– 追記
調べた。
このページがわかりやすい、かも。
つまり、
> MStatus NAME##_stat;
ってのは、
> MAKE_NUMERIC_ATTR( radius1, “r1″, MFnNumericData::kDouble, 1.0, true );
だと、プリプロセッサは、
> MStatus radius1_stat;
に置き換えるってことですか。
なんだ関数マクロってこんな機能あるのか。便利じゃないか。
便利な反面、気をつけねばいかん機能であるのも事実ですが。
世の中の、その辺に落ちているプラグインを見てもそう書かれて無いのは、みんなしてこれの危険性を知ってるからなのか、なんとなく嫌いだからなのか、もしくはそもそもそういう書き方をしらないからなのか(ってそんなことはないか)。
むむむ、、
でも前に某社のプログラマさんが自前ライブラリでこんな書き方してるの見た!ので、
なんとなく好みの問題なのかな、なんて思ったりもします。
———————————————————– 追々記
こちらはインライン関数に関してのページ。
併せてメモ。
- Newer: [Maya API]ものすごいハマった(良くない意味で)
- Older: [Python] super()
Comments:9
- @h 2008/12/11
プリプロセッサだけの
ツールとかもあるので使ってみると便利かもですよー俺の主観ですが
レンダラ書きは早いからプリプロセッサ大好きみたいですよ- hohehohe2 2008/12/11
defineに限った話ですが、
1)
#define times2(x) x * xだとtimes2(a++)のように関数っぽく使えるのにaの値が2増える。2)
#define times(x, y) x * yだとtimes(a, b + 1)でa*b+1が返ってくる。: (x) * (y)とする必要有り、3)も考えて((x) * (y))3)
#define add(x, y) x + yだとadd(a, b) * cでa+b*cが計算される:2)も考えて((x) + (y))4)デバッガやプロファイラが役に立たないことが多い。
5) 誰かがdefineしたものを関数名などで知らずに使ってしまう。
6) 誰かがdefineしたものを知らずに再度defineしてしまう
7) 別々の定義でdefineされたものが矛盾する時がある
5)6)7)のためdefineは特にヘッダファイルにある時かなり危険です。バグの原因突き止めるだけで丸一日かかることもあります(Javaでは便利さよりも危険性を重視してdefineをなくしました)。逆にプラグインなど比較的小さく独立したプログラムで、効率など他の要素がない時はそれほど意識しないでもいいと思います(が気にする人もいるので他人が見る所ではなるべくconstやinline関数を使うようにはしています)。
- tai 2008/12/11
>@hさん
> プリプロセッサだけのツール
おおお?プリプロセッサだけのツールというと、、、何をするものなんでしょうか。。> レンダラ書きは早いからプリプロセッサ大好きみたいですよ
プリプロセッサ=置き換えだから関数呼び出しのオーバーヘッドが無くなって速い、ってことなんでしたっけ。
まぁ、速ければ使いますよねww>hohehohe2さん
おおおおおおおおおお
詳細の説明ありがとうございます!1)はつまりx++ * x++になっちゃうので2増える、ってことなんですかね。
2)、3)、4)は聞いたことあるような気がします。
これって面白いですよねー。ダメなんだけど思わず感心してしまいましたwwww
5)、6)、7)は運用上のエラー、って感じですか。> 5)6)7)のためdefineは特にヘッダファイルにある時かなり危険です。
なるほど、、、確かに見落としてしまいそうです。
名前の上書きとかは相当怖いですね、、、
やっぱりこの辺はルール決めてやるしかないですね。> 逆にプラグインなど~
こちらも納得です。
つーことはとりあえず使っちゃイカン!ってモノではなくて、気をつけて使う分にはOKっぽそうですね。
僕も人が見る部分(ほとんど無いと思うけど)ではconst、inline方式でやってみます:)ありがとうございまーす!
- hohehohe2 2008/12/12
> 1)はつまりx++ * x++になっちゃうので2増える、ってことなんですかね。
そうです。
> 名前の上書きとかは相当怖いですね、、、
> やっぱりこの辺はルール決めてやるしかないですね。避けられない理由があることもありますが人が使うの前提のライブラリのヘッダとかには理由がない場合使わない方がいいですねー。namespaceの中に関数かクラス入れとくのが安全だと思います。
> つーことはとりあえず使っちゃイカン!ってモノではなくて、気をつけて使う分にはOKっぽそうですね。
あくまで自分の感想なんであんまり参考にしないでくださいw。
- @h 2008/12/12
プリプロセッサの動作って
コンパイル前に規則に従って
文字列置換してるわけなのでjavaとか
pythonでも
プリプロセッサみたいなソフトを使うことが出来ます。
ただし、手動でソフトを起動する必要はありますが・・・wプリプロセッサを使う利点としては
主に
ソースを読み易くしたり関数にしない分
関数呼び出しのオーバヘッドタイムを減らしたりするのに
使ってると思います。- tai 2008/12/12
>hohehohe2さん
>人が使うの前提のライブラリのヘッダとかには〜
自分以外の人が使うか否か、ってのがポイントですね。
考えうる限りまだそういう事態にはならなさそうなのですが、
気をつけるに越したことはないですし、意識しておこうとおもいます:Dありがとうございますーっ。
- chiyama 2008/12/12
未来の自分も他人みたいなモノですよw
私は極力使わないようにしてます。hohehohe2さんが
詳しく書かれてますけど、これでハマって一日潰すと
かなり切ないです(経験多数ww- hohehohe2 2008/12/12
そうですね、コードがリユースされる可能性のある時には避けた方がいいと思います。
- tai 2008/12/12
>@hさん
あ、すごいタイミングで書き込みがかぶってたみたい、、
遅レスサーセン。。
> プリプロセッサもどき
自分で置き換えってのは考えたこともなかったですwwwww
余計にややこしくなりそうwwwwwwwww>chiyamaさん
> 未来の自分も他人みたいなモノ
た、たしかに、、
やっぱりバグの温床になりやすいものなんですかねー。>hohehohe2さん
うす、気をつけます。みなさま経験豊富なので非常に参考になります。
ありがとうございます:)
Trackbacks:0
- Trackback URL for this entry
- http://blog.taikomatsu.com/2008/12/10/cc%e3%83%9e%e3%82%af%e3%83%ad/trackback/
- Listed below are links to weblogs that reference
- [C/C++]マクロ from memlog