質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

2157閲覧

C言語のマクロがわからない

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/07/02 15:54

編集2017/07/02 16:20

いつもお世話になってます。

現在、C言語のためのエラー処理を描こうとしているのですがマクロで悩んでいます。
まず、2つのec_nullとec_cmpという以下のマクロがあります。ec_nullのprinte関数はエラーが起きたファイルや行数など諸々の情報を出力するだけです。

lang

1/* x と val を比較して一緒だったらエラー */ 2#define ec_cmp(x, val) \ 3{\ 4 if ((intptr_t)(x) == (intptr_t)(val)) \ 5 return true;\ 6} 7 8/* x と NULL を比較する */ 9#define ec_null(x) \ 10{\ 11 if (ec_cmp((x), NULL))\ 12 printe("File <%s> Function <%s> Line <%d> returned NULL", __FUNCTION__, __FILE__, __LINE__);\ 13} 14 15

そして、ec_nullは、例えばmallocの時のチェックに使いたいと思っています。

mem = malloc(100) ec_null(mem)

ですが、これをコンパイルしようとすると以下のようなエラーが出ます。

test.c:28:3: error: expected expression ec_null(NULL); # わざとNULLを入れてテスト ^ ./ec.h:6:7: note: expanded from macro 'ec_null' if (ec_cmp((x), NULL))\ ^ ./ec.h:11:24: note: expanded from macro 'ec_cmp' #define ec_cmp(x, val) \

マクロをよく理解していないことが原因だと思い自分でも色々と調べてみたのですが、未だに理由がわかりません。
何がいけないのでしょうか? また、エラー処理としてもっとうまい方法があれば、よろしくお願いします。

********************** 追記 *************************
色々と試していたのですが、x と val の比較 if ((intptr_t)(x) == (intptr_t)(val))を以下のように直接ec_nullに入れると動きました

lang

1#define ec_null(x)\ 2 {\ 3 if ((intptr_t)(x) == (intptr_t)(NULL)) \ 4 printe("File <%s> Function <%s> Line %d returned NULL\n", __FUNCTION__, __FILE__, __LINE__);\ 5 } 6

ということはec_cmpをif文の中に入れていたのがいけなかったということでしょうか? それかec_cmpからreturnするということについて何かおかしかったのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

マクロは単純に文字列の置き換えです。
ですので、ec_null(mem)は次のように置き換えられます。

C

1{\ 2 if (ec_cmp((mem), NULL))\ 3 printe("File <%s> Function <%s> Line <%d> returned NULL", __FUNCTION__, __FILE__, __LINE__);\ 4}

そして、if (ec_cmp((mem), NULL))は次のように置き換えられます。(改行と\を削除しました。)

C

1if ({if ((intptr_t)((mem)) == (intptr_t)(NULL)) return true;})

if文の条件の中に{}ブロックが入ってますが、これはC言語の構文として間違っています。

下記でコンパイルできると思います。

C

1#define ec_cmp(x, val) ((intptr_t)(x) == (intptr_t)(val))

【補足】
マクロは全部大文字で単語の区切りを _とする記法が、非常に優勢です。体感では99%以上。
ですので、EC_CMP()やEC_NULL()のような命名の方が好まれることが多いと思います。

マクロは、Cコンパイラではなくプリプロセッサが処理するもので、文法も振る舞いも大きく異なるのでひと目で分かるようにしたい人が多いからだと思います。

投稿2017/07/02 16:15

編集2017/07/02 16:19
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/02 16:23

if文の中の{}がいけなかったのですね。 疑問が解決しました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問