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

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

ただいまの
回答率

90.48%

  • C

    3820questions

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

C言語 マクロ 定義

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 650

ikasoumen

score 92

C言語のマクロの挙動について詳しい本や参考ホームページなどあれば教えていただけないでしょうか。
私が持っている参考書ではあまりマクロについて取り扱っておらず、つまづいてしまいました。

参考までに、今つまづいているソースコード箇所を抜粋します。
宜しくお願いします。
URL

#if defined(LUA_BUILD_AS_DLL)    /* { */

#if defined(LUA_CORE) || defined(LUA_LIB)    /* { */
#define LUA_API __declspec(dllexport)
#else                        /* }{ */
#define LUA_API __declspec(dllimport)
#endif                        /* } */
#else                /* }{ */
#define LUA_API        extern
#endif                /* } */

//どう置き換わるのかよくわからない
LUA_API int             (lua_isnumber) (lua_State *L, int idx);
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+2

マクロの挙動というよりはプリプロセッサの挙動でしょうか。
何も難しく考えることはありません。
質問にあるようなソースも普通のプログラムと同じ考え方で読み解けます。

#if defined(LUA_BUILD_AS_DLL)    /* { */


LUA_BUILD_AS_DLLが定義されていれば?ですね。

#if defined(LUA_CORE) || defined(LUA_LIB)    /* { */


LUA_COREまたはLUA_LIBが定義されていれば?ですね。

#define LUA_API __declspec(dllexport)


マクロ LUA_APIを__declspec(dllexport)で定義する、ですね。

と、順を追って読んでいけば難しいことはありません。
ただし、#if define(MACRO) で見ているマクロが定義されているかというのは、ソースファイルを検索するなりするしかないですが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 09:25

    ありがとうございます。
    そもそもマクロ以外のところが分かってませんでした。
    LUA_BUILD_AS_DLL → linux に dll ってあったっけ? フラグはコンパイルするときにオプションで立てるのかな?
    LUA_CORE →なんだろう?
    LUA_LIB →なんだろう?
    LUA_API __declspec(dllexport)→調べてみます
    LUA_API __declspec(dllimport)→調べてみます

    っていう状態です。

    キャンセル

  • 2016/04/21 09:40

    LUAのソースをダウンロードして見てみました。
    時間がないのでLUA_BUILD_AS_DLLだけしか確認してませんが、これはMakefile内で指定しているようです。

    mingw:
    $(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
    "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
    "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
    $(MAKE) "LUAC_T=luac.exe" luac.exe

    SYSCFLAGS=-DLUA_BUILD_AS_DLL の箇所ですね。
    つまりMinGW環境でメイクするときには有効になるマクロということになります。

    このソースはLUA自体のメイク用っぽいので、LUAを使うユーザーは細かいことは気にすることないのではと思います。
    LUAのソースを解析したい!というのなら話は別ですが。

    キャンセル

  • 2016/04/21 22:12

    ありがとうございます。
    これから簡単な式計算ができる関数電卓でも作ろうかなと思ってまして参考にソースを解析してます。
    上手いソースの分割の仕方とかリンクとかよく分かってないので勉強したいと思います。

    キャンセル

0

こんにちは。

プリプロセッサでプログラムの質を向上させよう (2/4)は適度に網羅されていて良さそうですよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 09:08

    ありがとうございます。参考にさせていただきます。

    キャンセル

0

 #if / #else / #endif は、C言語の構文で言うところのif文と同じです。
これでいうとまず LUA_BUILD_AS_DLL が定義されていれば#elseまでが展開され、未定義なら LUA_APIはexternに置き換わります。
LUA_BUILD_AS_DLL が定義されていてかつ LUA_CORE または LUA_LIB が定義されていれば LUA_APIは declspec(dllexport)に置き換わり、どちらも未定義なら declspec(dllimport) に置き換わります。
つまり、 LUA_API int (lua_isnumber) (lua_State *L, int idx); の関数定義を外部定義なのかDLLインポートなのかまたはエクスポートなのかをLUA_****の定義の有無で切り替えているわけです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 09:20

    ありがとうございます。
    マクロよりも、ビルドに関する知識がないのでまずそちらを勉強してみます。

    キャンセル

0

どう置き換わるのかよくわからない

ということのようですので、
ご期待されている回答ではないかもしれませんが
プリプロセッサの結果を出力してみるのはいかがでしょうか。

プリプロセッサの結果を出力するには、コンパイルオプションを指定します。
コンパイラーによって異なり、
GCCなら-Eオプション、
Visual StudioのC/C++なら/Pオプションでできるようです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 09:25

    ありがとうございます。
    試してみたいと思います。

    キャンセル

0

読み方は先に答えていらっしゃる方がたくさんいますのでそちらを読んでくだされば大丈夫だと思いますけど,要は文字列の置換です.
たんに  #define AAA BBB  だけなら AAA と定義された文字が BBB に置き換わるだけですけど,
#if defined(~) みたいにdefineされていたら,っていうのは状況によって差し替える用途に使うことが多いんじゃないですかね?

たとえばDebug時とRelease時で違う挙動をしたい,とかね.

ただの置換と違うところはこのように状況に応じて使い分けることが出来る(置換しちゃうと変える,ってことは出来ない)んだとイメージすれば良いんじゃないかな?と思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/21 09:28

    ビルドの知識がないので勉強してみたいと思います。
    デバッグでビルドするとデバッグシンボルが出力されたような。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • C

    3820questions

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