C言語のネストしたプリプロセッサ命令について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
KA582
記事: 4
登録日時: 12年前

C言語のネストしたプリプロセッサ命令について

#1

投稿記事 by KA582 » 12年前

初めて利用させていただきます<(_ _)>

C言語でマクロを使って定数値を定義したいと考えています。
既にどこかで同名のマクロが定義されている場合は、そちらを優先したいので、
次のような定数値を定義してくれるマクロを定義しました。

コード:

/**
 * @brief 同名のマクロが存在しない場合にマクロを定義します。
 * @param define_name 定義するマクロ名
 * @param define      マクロの定義
 */
#define NON_OVERWRITE_DEFINE(define_name, define) \
	#ifndef define_name \
	#define define_name (define) \
	#endif
このマクロを利用して定数値を定義するコードが以下になります。

コード:

NON_OVERWRITE_DEFINE(M_PI, 3.14159265358979323846)
しかし、コンパイルエラーになってしまいます。
エラーメッセージは
・error C2162: 文字列化演算子 (#) の後のトークンは、仮引数名でなければいけません。
・error C2146: 構文エラー : ';' が、識別子 'M_PIE' の前に必要です。
・error C2143: 構文エラー : ';' が '文字列' の前にありません。
というものが表示されます。

エラーメッセージから、ネストしたプリプロセッサ命令が問題(#が演算子と被る)だと思うのですが、
このエラーを解決する方法か、代替案があれば、教えていただきたいです。

salsaww

Re: C言語のネストしたプリプロセッサ命令について

#2

投稿記事 by salsaww » 12年前

やりたい事も分かるのですが、
習慣として、素直なマクロの使い方の方がいいと思います。
 (自分がC++派の人間なので、
 そもそも#include や__FILE__など以外のマクロを使用するという状態が、非常に危ない兆候と見るのもあって)

また、基本的に予期せぬマクロの再定義(※値が同じ場合は無視される。)はエラーになるオプションなどがあるか、
基本としてエラーかWarningを吐かれると思うので、通常の利用方法で特別に問題は発生しないと思われます。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: C言語のネストしたプリプロセッサ命令について

#3

投稿記事 by beatle » 12年前

行末に\があるので、実は4行ではなく1行のマクロ定義になっています。

コード:

#define NON_OVERWRITE_DEFINE(define_name, define)     #ifndef define_name     #define define_name (define)     #endif
プリプロセス命令は、#より左側には空白文字しか来てはいけません。すなわち、一番左の#defineのみが正当なプリプロセス命令として認識されます。
解決策は今は特に思い浮かびません。
僕だったら#ifndefを愚直にたくさん書くかなあと思います。

KA582
記事: 4
登録日時: 12年前

Re: C言語のネストしたプリプロセッサ命令について

#4

投稿記事 by KA582 » 12年前

>>salsawwさん
>また、基本的に予期せぬマクロの再定義(※値が同じ場合は無視される。)はエラーになるオプションなどがあるか、
基本としてエラーかWarningを吐かれると思うので、通常の利用方法で特別に問題は発生しないと思われます。

僕としては、このエラー自体を発生させないための方法を考えていました。
例えば、自分のソースコードで再定義エラーが発生したのなら解決する事が出来ますが、
ライブラリなどとして提供した場合にユーザーがエラーを修正しようと思ったら「編集権限がなかった!」という事が考えられますので・・・。
この問題に関してはそもそも被らない名前を考えた方が近道なのかもしれませんが。

>>beatleさん
>行末に\があるので、実は4行ではなく1行のマクロ定義になっています。

なるほど!
\による改行はてっきり展開時にも影響を受けて実改行が挿入されると思っていたのですが、
そうではないのですね。


僕もあれから良い案が思い浮かばなかったことと、
salsawwさんやbeatleさんの素直なマクロの使い方の方がいいという意見から、
#ifndefを手動で記述していく事で、解決とさせていただきます。

salsawwさん、beatleさん、回答ありがとうございました。

閉鎖

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