2013-03-27 14 views

答えて

12

あなたが機能を持っており、関数のようなマクロがfooという名前と機能バージョンを呼び出したいの両方の場合は、あなたが行うことができます:

(foo)(args) 

関数のようなマクロ名が続かなければなりませんので、これは動作します置換を行うための引数リストをカッコで囲んだもの。

これはISO C99標準規格のセクション7.1.4/1に記載されている:

ので、もしヘッダ内で宣言する関数は、さらに、ヘッダに定義された関数のようなマクロとして実装することができますライブラリ関数は、そのヘッダが含まれているときに明示的に宣言されていますが、そのようなマクロの影響を受けないように、以下に示す手法の1つを使用できます。関数のマクロ定義は、関数の名前をカッコで囲むことでローカルに抑制することができます。名前の後にマクロ関数名の展開を示す左括弧がないためです。同じ構文上の理由から、たとえそれがマクロとして定義されていても、ライブラリ関数のアドレスを取ることは許されます。任意のマクロ定義を削除するために#undefを使用することにより、実際の関数が確実に参照されるようになります。

しかし、これを行う必要がある場合は、少し奇妙に見えて一般的な方法ではないため、コメントにコードを追加する必要があります。実現可能であれば、名前の衝突を避けるために関数の名前を変更することは、長期的にはより保守的かもしれない。

+0

サイドノート、C++の状況はまったく同じです。 – Potatoswatter

+0

ええ、元の質問のアプローチは、下流のメンテナンスの恐怖を呼び起こします。もし彼がそうしなければならないなら、これは方法です。 –

1

名前を変更してください。または、それが可能でない場合は、マクロを定義してそのポインタを介して関数を呼び出す前に、元の関数へのポインタを作成してください。

+0

明示的な行動を持っています。 'foo'と'&foo'は関数のようなマクロ呼び出しを引き起こしません。しかし、これはオブジェクトのようなマクロのための正しいソリューションです。 – Potatoswatter

1

は、コール

#ifdef foo 
#undef foo 
#endif // 

前にトリックを提供しますので、ローカル関数を呼び出し、単一のファイルには、常にマクロがその関数のアドレスを取るとは干渉しません

+1

しかし、マクロをバックアップして復元する方法はないので、関数呼び出しの後で使用する必要はありません。 – Potatoswatter

関連する問題