2017-06-20 12 views
1

#ifステートメントの内部で使用しても素晴らしい警告を出力するようにマクロを非難します。#if文でマクロを使用すると非推奨の警告を表示します

This answerは私が望むものとほとんど同じですが、#ifステートメント内からマクロにアクセスするとエラーが発生します。

#include <stdio.h> 

#define DEPRECATED_CONSTANT _Pragma ("GCC warning \"Deprecated constant!\"") 0 
#define DEPRECATED_FUNCTION(...) _Pragma ("GCC warning \"Deprecated function!\"") printf(__VA_ARGS__) 

int main() { 
    // Prints a warning (good) 
    int n = DEPRECATED_CONSTANT; 

    // Prints a warning (good) 
    DEPRECATED_FUNCTION("%d\n", n); 

// Throws an error (bad) 
#if DEPRECATED_CONSTANT 
    return 1; 
#else 
    return 2; 
#endif 
} 

エラーは次のとおりです。

error: missing binary operator before token "(" 

ボーナスポイントあなたは私のクロスプラットフォーム互換性の解決策を見つけることができれば!

EDIT

私は優雅に、ライブラリ内の破壊変更を処理しようとしている - 私は、彼らが古いマクロを使用するたびに、ユーザーが素敵な、明確な警告(またはエラー)を持つようにしたいので、それがされます新しいマクロを使用するようにコードを移行する必要があることを明確にしてください。これらのプラグマ・ソリューションは、その定数の値がプリプロセッサ・ディレクティブでアクセスされるのではなく、コードで使用される場合にのみ機能します。

以下の回答によれば、この問題の解決策はないようです(clangを使用している場合を除きます)。みんな、ありがとう。

+0

コンテキストを追加できますか。 '#if DEPRECATED_CONSTANT'と書くことで、何をテストしたいですか?マクロが定義されているかどうかテストしますか? – Stargateur

+0

マクロが何らかの方法で使用されているときはいつでも非推奨警告を表示したいと思います。 –

+0

私はあなたのユースケースが '#ifdef'を使用できないと仮定していますか? – DIMMSum

答えて

4

#if文の内部で使用されても、素晴らしい という警告が表示されるようにマクロを非難したいと考えています。

私はカンマ演算子を提案しようとしていましたが、_Pragmaマクロがおそらく実際のコードを生成しないため、動作していないようです。また、GCCは、少なくとも、明示的にあなたは_Pragma()で提案し何ができないと言う。

https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html

標準は_Pragma演算子が表示されることができる場所では不明です。 プリプロセッサーは、 '#if'のような前処理条件付き 指令内では受け付けません。安全であるためには、おそらく '#define'以外のディレクティブ を残しておいて、それを 自身の行に置くのが最も良いでしょう。

PS - 打ち鳴らす8.1.0は、あなたのプログラム上のエラーではありませんでしたし、必要な警告を与えた...

1

@ jschultz410は述べているように、何をやろうとしていることは明示的にはgccで禁止されている(参照https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html)。

ネストされたマクロは、このようなユースケースのために適切なようだ:

#include <stdio.h> 

#define DEPRECATED_CONSTANT_VALUE 0 
#define DEPRECATED_CONSTANT _Pragma ("GCC warning \"Deprecated constant!\"") DEPRECATED_CONSTANT_VALUE 
#define DEPRECATED_FUNCTION(...) _Pragma ("GCC warning \"Deprecated function!\"") printf(__VA_ARGS__) 

int main() { 
    // Prints a warning (good) 
    int n = DEPRECATED_CONSTANT; 

    // Prints a warning (good) 
    DEPRECATED_FUNCTION("%d\n", n); 

// Throws an error (bad) 
#if DEPRECATED_CONSTANT_VALUE 
    return 1; 
#else 
    return 2; 
#endif 
} 

はい、これは総の一種であるが、我々はすでに設計優雅さのいずれかの種類にあきらめているプリプロセッサロジックの地で最初の場所。少なくともこのようにして、マクロインターフェイスは非プリプロセッサコードで維持されます。 (これは、#ifステートメントでプリプロセッサの警告を表示しませんでしたが、残念ながらこれはgccでは不可能です)。

関連する問題