ページ 11

マクロで配列を初期化

Posted: 2011年7月27日(水) 11:41
by りった
■現状の処理
#define ARINIT(a,b...) = {a, ## b} ;
#define YYY_MAX = 4 ;
:
char xxx[YYY_MAX]=ARINIT(0,0,0,0) ; ・・・・(1)

■背景
機能アップしたため、YYY_MAXを5にすることになりました。
尚、いたる所が腐ってるソースなので、大がかりなことは出来ません。)

■質問
今後のことを考え、(1)の部分を変更せずにYYY_MAXを変更出来る形にしたいですが可能でしょうか?

Re: マクロで配列を初期化

Posted: 2011年7月27日(水) 12:02
by bitter_fox
りった さんが書きました:■現状の処理
#define ARINIT(a,b...) = {a, ## b} ;
#define YYY_MAX = 4 ;
:
char xxx[YYY_MAX]=ARINIT(0,0,0,0) ; ・・・・(1)

■背景
機能アップしたため、YYY_MAXを5にすることになりました。
尚、いたる所が腐ってるソースなので、大がかりなことは出来ません。)

■質問
今後のことを考え、(1)の部分を変更せずにYYY_MAXを変更出来る形にしたいですが可能でしょうか?
えっと、色々気になる点があるのですが・・・

まず、マクロ定義内で=を使うのはよろしくありません。
char xxx[YYY_MAX]=ARINIT(0,0,0,0) ;を質問者さんの定義で展開しますと、
char xxx[= 4 ;]== {0, 0, 0, 0} ; ;のようになってしまいそもそもコンパイルが通りません。

また、{a, ## b}の所もなぜ##を使用しているのかよく分かりません。
ここは単に{a, b}とするだけではよいのではないでしょうか?

配列を0で初期化したいのであれば次のようなテクニックで初期化できますよ。

コード:

#define ARR_MAX 4

char xxx[ARR_MAX] = {0};

Re: マクロで配列を初期化

Posted: 2011年7月28日(木) 09:33
by りった
回答ありがとうございます (^^)

> char xxx[= 4 ;]== {0, 0, 0, 0} ; ;のようになってしまいそもそもコンパイルが通りません。

失礼しました。再度確認したところ下記でした。
char xxx[YYY_MAX] ARINIT(0,0,0,0) ; ・・・・(1)
(開発マシンからネット繋げないので、転記した際ミスりました。)

> また、{a, ## b}の所もなぜ##を使用しているのかよく分かりません。
すみません。自分にも分かりません。
何百か所も使っているので、修正困難です。(単体試験工数を確保出来ない)

> char xxx[ARR_MAX] = {0};
なるほど。単純にこれでいけるんですね。これなら単体試験範囲も増えないので大変助かります。
ちなみにコンパイラーに依存するか否かご存じでしたら教えてください。
こちらのコンパイラーが何かは分かってません。
入ったばかりなので、「コンパイラー依存するコード書くな!!」と怒られても困るので聞けません。

Re: マクロで配列を初期化

Posted: 2011年7月28日(木) 10:06
by softya(ソフト屋)
##の意味は下記を読んでください。
「C言語 プリプロセッサ」
http://itref.fc2web.com/c/preprocessor.html
まだ写し間違いの可能性があると思います。
りった さんが書きました:ちなみにコンパイラーに依存するか否かご存じでしたら教えてください。
こちらのコンパイラーが何かは分かってません。
入ったばかりなので、「コンパイラー依存するコード書くな!!」と怒られても困るので聞けません。
最近のコンパイラーなら大丈夫だと思いますが、古かったりすると0クリアをしないかも知れません。
組み込み系のコンパイラの場合はスタートアップルーチンにも依存します。

それと
char xxx[ARR_MAX] = {0};
は0クリアする場合には有効ですが、それ以外の値を入れる場合には向きません。

Re: マクロで配列を初期化

Posted: 2011年7月28日(木) 10:48
by bitter_fox
りった さんが書きました: 失礼しました。再度確認したところ下記でした。
char xxx[YYY_MAX] ARINIT(0,0,0,0) ; ・・・・(1)
(開発マシンからネット繋げないので、転記した際ミスりました。)
マクロ定義は同じですか?
だとしたら
char xxx[= 4 ;] (ry
となってしまい、まだコンパイルできません。
りった さんが書きました: > また、{a, ## b}の所もなぜ##を使用しているのかよく分かりません。
すみません。自分にも分かりません。

こちらのコンパイラーが何かは分かってません。
色々調べてみるとgccでは可変個引数に対して##を使うと次のような効果があるようです。
http://www.02.246.ne.jp/~torutk/cxx/tips/varargs.html

また、本来の可変個引数の書き方は

コード:

#define MACRO(format, ...) printf(format, __VA_ARGS__)
になりますので、りったさんが載せた可変個引数の書き方ではコンパイルできない可能性があります(VCではコンパイルできませんでした)。
ただ、gccだとりったさんの可変個引数の書き方でもコンパイルできました。(http://ideone.com/GmJpy)

これらの事からコンパイラはgccではないですか?
りった さんが書きました: 何百か所も使っているので、修正困難です。(単体試験工数を確保出来ない)
入ったばかりなので、「コンパイラー依存するコード書くな!!」と怒られても困るので聞けません。
あと、話を聞くと会社のコードのように思えるですが、そうだとしたらこのコードは勝手に持ち出しても良いものなのでしょうか?

Re: マクロで配列を初期化

Posted: 2011年7月28日(木) 14:58
by りった
回答ありがとうございます。大変助かりました。

> あと、話を聞くと会社のコードのように思えるですが、そうだとしたらこのコードは勝手に持ち出しても良いものなのでしょうか?
ソース丸ごとだとまずいので、ピンポイントだけ抜き出して変数名変えてます。
一般的な質問レベルになっているので大丈夫だと思います。

Re: マクロで配列を初期化

Posted: 2011年7月28日(木) 18:07
by ISLe
解決したんですか?
転記ミスを指摘されただけで質問者さんが知りたいことは書かれてないような…。

#define YYY_MAX 4

#define YYY_MAX 5
にするだけで、自動的に増えた要素が0で初期化されますよね。

増えた要素を0以外で初期化したいとなれば何百ヵ所も変更する必要がありますが。