マクロ関数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
cn

マクロ関数について

#1

投稿記事 by cn » 13年前

はじめまして。cnと申します。

現在マクロ関数の定義の方法について悩んでいます。
次のような定義があったとき、

コード:

/* code 1*/
#define Get(n,type) ((type) n)
typedef unsigned int my_u_int
typedef signed int my_s_int
typedef float my_float
Get関数を次のように呼びたいです。

コード:

/* code 2 */
#define GetType(i) ((i==0) ? my_u_int : ((i==1) ? my_s_int : my_float))

int main() {
  int t=0;
  /* tが変化 */
  double g = Get(123.456,GetType(t));
  return 0;
}
非常にややこしいですが、やりたいことは次のとおりです。
・code1の定義は絶対に変更できない
・変数tの結果によってGet関数の第2引数を {my_u_int, my_s_int, my_float}のいずれかにする(tは0~2の間であると仮定する)←これをマクロ化したい
そこで登場したのがcode2のGetType関数です。
しかし、これではコンパイルが通りません。(当たり前ですが)

コード:

error: expected expression before ‘my_u_int’
error: expected ‘)’ before numeric constant
このような感じにコードを(なるべくスマートに)書こうとしたらどのように書けば良いのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: マクロ関数について

#2

投稿記事 by softya(ソフト屋) » 13年前

マクロは関数ではありません。
なので動的に変化する変数とコンパイル時に確定するのもの(マクロ)を同義に扱ってもうまくいくことはありません。

そもそも、こんな変換をしたい意図を教えて下さい。
あとC++は使っても良いのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: マクロ関数について

#3

投稿記事 by YuO » 13年前

C/C++において,型は静的に決まらないといけません。
故に,実行時の値によって型を切り替えることはできません。

各型用のコードを用意して,switch等で呼び出しをかえることになります。
# templateで共通化できる可能性もあります。

cn

Re: マクロ関数について

#4

投稿記事 by cn » 13年前

softyaさん、YuOさんご回答ありがとうございます。

>そもそも、こんな変換をしたい意図を教えて下さい。
今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef struct(今後これをTYPEと呼びます。)されています。
TYPEはa={signed, unsigned, float} b={4, 8, 16, 32, 64}の二つの条件から成り立っています(実際は9個)。
プログラム内で

コード:

if (aa==signed && bb==4} {...} else if {aa==unsigned && bb==4} {...} ...
[/codel
のように毎回条件分岐を書くのがとても億劫に感じていたから、GetType関数のようにできらた楽かなと考えたからです。

>あとC++は使っても良いのでしょうか?
g++4.5.2でコンパイルできるなら問題ありません。


># templateで共通化できる可能性もあります。[/quote]
簡単にでも教えていただけると助かります。

cn

Re: マクロ関数について

#5

投稿記事 by cn » 13年前

☓今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef struct(今後これをTYPEと呼びます。)されています。
○今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef(今後これをTYPEと呼びます。)されています。

アバター
ookami
記事: 214
登録日時: 14年前
住所: 東京都

Re: マクロ関数について

#6

投稿記事 by ookami » 13年前

こんにちは、ookamiです。
自信ないですが
#define GetType(i,v) ((i==0) ? Get(v,my_u_int) : ((i==1) ? Get(v,my_s_int) : Get(v,my_float)))
:
:
double g=GetType(t,123.456)
という感じでしょうか?
この場合は型変換の警告が出ると思いますが...

利用シーンがよく分からない...^^;

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: マクロ関数について

#7

投稿記事 by softya(ソフト屋) » 13年前

すいません出かけていて返答が遅くなりました。
ookamiさんのでOKだと思いますが私も必要性を感じません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

cn

Re: マクロ関数について

#8

投稿記事 by cn » 13年前

ookamiさん、softyaさんご回答ありがとうございます。

まず説明不足であったことの謝罪をさせてください。
申し訳ありませんでした。

いわゆる画像ライブラリで、1ピクセルあたりの型を指定できます。
それが{signed, unsigned, float} {4, 8, 16, 32, 64}です。
画像用構造体にはこの情報が含まれています。
また、このライブラリではTYPEを引数にした関数がたくさんあります。
例えば画素値を取得するには

コード:

valus = Get (image, x, y, plane, TYPE)
のような関数が存在します。
このとき、TYPEを動的に変えたいと考えています。
本来ならば

コード:

if (signed && 4) then {
   values = Get (image, x, y, plane, s_char)
} else if (unsigned && 4) then {
   values = Get (image, x, y, plane, u_char)
} else if (....)
...
..
.
とするべきなのですが、引数としてTYPEを使う関数が多く、
すべての関数でこのような分岐を書かなければならず、簡潔に書けないかと考えていました。
そこで、マクロを使えば

コード:

values = Get (image, x, y, plane, MACRO(val))
のように一行で書けるのではないかと考えた次第です。

>ookamiさん
なるほど。Getをラップするような形にすればできますね。
マクロ定義自体は長くなりますが、とても簡潔です。
一度この手法で実装を行ってみようと思います。

ありがとうございます。
(そもそも根本的に考え方?が不適切かもしれません・・・)

閉鎖

“C言語何でも質問掲示板” へ戻る