7

まず、警告で停止したい。しかし、いくつかの有益なメッセージ (「戻ってきて、これを実装してください!」など) も出力したいと思います。

#info残念ながら、私のコンパイラは、#message#pragma message()などをサポートしていません。

があることは知って-Wno-error=<something>いますが、私の google-foo は弱く、 for を見つけることができないよう<something>です#warning。を試してみましたが-Wno-error=warning、「ありません-Wwarning」とだけ表示されます。「warn」も同様です。

助言がありますか?

その価値のために、私は Tensilica Xtensaコンパイラー xt-xcc を使用しています。これは GNU の派生物であるか、少なくとも GNU フロントエンドを使用しているようです。バージョン 8.0.0 です。

4

6 に答える 6

3

Tensilica Xtensa コンパイラ ( xt-xcc) には詳しくありませんが、標準の GCC では使用できます

  #pragma GCC diagnostic warning "-Wcpp"

#warning単純な警告の問題を作成します ( によるエラーではありません-Werror)。効果を一時的にするために、これ#pragmaと と の#warning#pragma GCC diagnostic pushに含めることができます#pragma GCC diagnostic pop

次を含むファイルをコンパイルすると

    #pragma GCC diagnostic push
    #pragma GCC diagnostic warning "-Wcpp"
    #warning one
    #pragma GCC diagnostic pop

    #warning two

-WerrorGCC 4.6.1 (コマンド)を使用gcc -c -Werror warning-test.cすると、次の出力が得られます。

```lang-none
warning-test.c:3:2: warning: #warning one [-Wcpp]
warning-test.c:6:2: error: #warning two [-Werror=cpp]
cc1: all warnings being treated as errors
```

2 番目の を削除すると#warning、エラーによってコンパイルが中断されることはありません。

-Werrorコンパイラ オプションを に置き換えることもできます-Werror -Wno-error=cpp。警告のカテゴリに含まれる他の影響を認識していないため (エラーとしてキャッチしたい他の場所にcpp正当なものがある可能性があります)、特定のエラーを一時的に無効にし、その直後に設定を復元する方がより正確な方法のようです。あなたの要件を満たすの。#warning#warning

GCC バージョン 4.8.4 および 4.9.2 を使用すると、ほぼ同じ動作になります (ソース行のみが追加で出力されます)。ただし、GCC バージョン 5.0.1 ( Ubuntu 15.04-Werror=cpp (Vivid Vervet) に含まれるプレリリース バージョン) を使用すると、オプションも含まれていない限り、2 つの警告が表示されます。そのため-Werror、新しい GCC では以前のように暗示されなく-Werror=cppなり、必要に応じて個別に提供する必要があるようです。

于 2012-09-24T04:53:43.377 に答える
1

#warning はおそらくプリプロセッサによって処理されるため、-Werror を指定せずにプリプロセッサを個別に実行し、プロプロセッサの出力で前処理を禁止してコンパイラを実行できます。

これを行うには、-Werror を除くすべての通常のオプションを使用してプリプロセッサを介して .c ファイルを実行し、出力を .i ファイル (C++ の場合は .ii) として生成します。コンパイラはこれらのファイルを前処理しないものとして認識するため、-Werror を指定してコンパイルできます。プリプロセッサが #warning をドロップし、コンパイラ自体によって処理されないと仮定すると、これで問題が解決する場合があります。

これはテストしていません。同じ問題に遭遇したとき、私は -Werror を使用せずにそれを受け入れることを選択しました。解決策は問題よりも複雑に見えました!

于 2011-05-05T10:16:01.027 に答える
1

残念ながら、私の特定のツールチェーンに対する答えはありません。テンシリカのエンジニアはそう言っています。#message や #pragma message() をサポートしていないか、 -Werror の存在下で#warningをエラーとして抑制する方法を知っています。

GCC ツールチェーンでは、 -Wno-error=[code] を使用して「この警告はエラーではありません」と言うことができますが、 #warning が取るコードに対応するリスト (またはコードはこれである可能性があります)。

標準の GCC コマンド ラインとプリプロセッサ ソース コードを掘り下げて、 -Wno-error= が何と等しいか、または -Werror= コードがあるかどうかのリストを見つけようとするかもしれません。 #警告に該当します。

于 2010-12-07T23:34:50.643 に答える
1

どうしたの:

#warning "Come back and implement this"
#warning "Do not do that!"
#warning "Must fix this before release"

通常、コンパイラは#warning、エラーまたは警告メッセージに引数 (または後のマテリアル) を含めます。

そして、通常、コンパイラが警告を必要とする何かを検出すると、それをかなり明確に報告します。


要件を考えると、これに対処する唯一の方法は#warningディレクティブを保護することだと思います...

#ifdef DO_WARNINGS
#warning "Some warning"
#endif /* DO_WARNINGS */

-DDO_WARNINGSほとんどの場合、 ;なしでコンパイルします。#warning警告を確認する必要がある場合( を使用-Werror)、-DDO_WARNINGSコンパイルが失敗することを受け入れて、結局含めます。make -k個々のコンパイルエラーが存在する場合でも、可能な限り多くのことを行うことを忘れないでください.


GCC 4.4.1 マニュアルのセクション 5.52.9 には次のように書かれています (一部):

5.52.9 診断プラグマ

GCC を使用すると、ユーザーは特定の種類の診断を選択的に有効または無効にしたり、診断の種類を変更したりできます。たとえば、プロジェクトのポリシーでは、すべてのソースを「-Werror」でコンパイルする必要がある場合がありますが、特定の種類の警告を許可する例外が特定のファイルにある場合があります。または、プロジェクトで診断を選択的に有効にし、定義されているプリプロセッサ マクロに応じてそれらをエラーとして扱う場合もあります。

#pragma GCC diagnostic kind option

診断の処置を変更します。すべての診断が変更できるわけではないことに注意してください。現時点では、警告 (通常は '-W...' で制御) のみを制御でき、すべてを制御できるわけではありません。'-fdiagnostics-show-option' を使用して、制御可能な診断とそれらを制御するオプションを決定します。kind は、この診断をエラーとして扱う場合は 'error'、('-Werror' が有効な場合でも) 警告として扱う場合は 'warning'、診断を無視する場合は 'ignored' です。option は、コマンド ライン オプションと一致する二重引用符で囲まれた文字列です。

#pragma GCC diagnostic warning "-Wformat"
#pragma GCC diagnostic error "-Wformat"
#pragma GCC diagnostic ignored "-Wformat"

これらのプラグマは、コマンド ライン オプションをオーバーライドすることに注意してください。また、これらのプラグマをソース内の任意の場所に配置することは構文的に有効ですが、サポートされている唯一の場所は、データまたは関数が定義される前です。そうしないと、オプティマイザーがソースを管理する方法によっては、予測できない結果になる可能性があります。同じオプションが複数回リストされている場合は、最後に指定されたオプションが有効になります。このプラグマは、コマンド ライン オプションを汎用的に置き換えることを意図したものではなく、プロジェクト ポリシーを厳密に制御するためのものです。

GCC は、コンパイル中にメッセージを出力するための単純なメカニズムも提供します。

#pragma message string

コンパイル時に文字列をコンパイラ メッセージとして出力します。このメッセージは情報提供のみを目的としており、コンパイルの警告でもエラーでもありません。

#pragma message "Compiling " __FILE__ "..."

文字列は括弧で囲むことができ、位置情報とともに出力されます。

#warning行を行に編集する気があるかどうかはわかりません#pragma message。それは問題を回避するでしょう-そして、より少ないコンパイラーでサポートされる可能性のある#warninginの周りに条件付きコンパイルを追加するよりも悪いだけです。#pragma message移植性の要件が何であるかによって異なります。

于 2010-12-07T04:41:23.060 に答える
0

コンパイラがサポートしている場合は、constructorfunction 属性を使用して、プログラムの開始時 ( の前main) に実行され、メッセージを stdout に出力する関数を定義してみてください。

#define TOKENPASTE(x, y) TOKENPASTE2(x, y)
#define TOKENPASTE2(x, y) x ## y
#define WARNING(message) \
  static void TOKENPASTE(_print_warning, __LINE__)() __attribute__((constructor)); \
  static void TOKENPASTE(_print_warning, __LINE__)() \
  { \
    puts(message); \
  }

WARNING("fix this before ship")  // prints out a message at runtime before main

これにより、コンパイル時ではなく実行時にメッセージが出力されます。これは、特に他のオプションがない場合は、ほとんど同じです。唯一の制限は、これを関数定義の外のグローバル スコープで使用する必要があることです。

于 2010-12-07T04:21:28.873 に答える