#warningプリプロセッサディレクティブの移植性
-
05-07-2019 - |
質問
#warningディレクティブは標準の C / C ++ではないことを知っていますが、gcc / g ++を含むいくつかのコンパイラがサポートしています。しかし、それをサポートしていない人は、黙って無視するのでしょうか、それともコンパイルに失敗しますか?つまり、サポートしていないコンパイラのビルドを壊すことなく、プロジェクトで安全に使用できますか?
解決
コンパイラが#warningをサポートしていない場合、エラーが発生する可能性があります。 #pragmaとは異なり、プリプロセッサが理解できないディレクティブを無視することは推奨されません。
とは言っても、さまざまな(かなり一般的な)プラットフォームでコンパイラを使用しており、すべて#warningをサポートしています。
他のヒント
MSVCは次の構文を使用することに注意してください:
#pragma message ( "your warning text here" )
通常の#warning構文は致命的なエラーを生成します
C1021: invalid preprocessor command 'warning'
したがって、これらのコンパイラに移植できません。
コンパイルにコードブロックが含まれていなくても、#warningを認識しないコンパイラから、少なくとも認識されないディレクティブ警告が表示される可能性があります。これはエラーとして処理される場合と処理されない場合があります-コンパイラは合法的にエラーとして処理することができますが、多くはより緩いものになります。
#warningを提供するGCC / G ++以外のコンパイラを知っていますか(名前を付けてください)? [編集済み: Sun Solaris 10(Sparc)およびStudio 11 C / C ++コンパイラは、どちらも#warningを受け入れます。]
Atmelプロセッサ用のコンパイラでこの問題が発生しました。また、未知の#warningトークンが原因でプリプロセッサエラーが生成されました。
残念ながら、解決策は、ソースツリー全体を変換して#pragmaと同等のものを使用し、gccを使用するとビルド動作が異なることを受け入れることであるように見えました。
mingwからvisual studioに切り替えるときに、グローバル構成ヘッダーにこのような行を追加しました。 (stdafx.hに含めます)
#ifdef __GNUC__
//from https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
//Instead of put such pragma in code:
//#pragma GCC diagnostic ignored "-Wformat"
//use:
//PRAGMA_GCC(diagnostic ignored "-Wformat")
#define DO_PRAGMA(x) _Pragma (#x)
#define PRAGMA_GCC(x) DO_PRAGMA(GCC #x)
#define PRAGMA_MESSAGE(x) DO_PRAGMA(message #x)
#define PRAGMA_WARNING(x) DO_PRAGMA(warning #x)
#endif //__GNUC__
#ifdef _MSC_VER
/*
#define PRAGMA_OPTIMIZE_OFF __pragma(optimize("", off))
// These two lines are equivalent
#pragma optimize("", off)
PRAGMA_OPTIMIZE_OFF
*/
#define PRAGMA_GCC(x)
// https://support2.microsoft.com/kb/155196?wa=wsignin1.0
#define __STR2__(x) #x
#define __STR1__(x) __STR2__(x)
#define __PRAGMA_LOC__ __FILE__ "("__STR1__(__LINE__)") "
#define PRAGMA_WARNING(x) __pragma(message(__PRAGMA_LOC__ ": warning: " #x))
#define PRAGMA_MESSAGE(x) __pragma(message(__PRAGMA_LOC__ ": message : " #x))
#endif
//#pragma message "message quoted"
//#pragma message message unquoted
//#warning warning unquoted
//#warning "warning quoted"
PRAGMA_MESSAGE(PRAGMA_MESSAGE unquoted)
PRAGMA_MESSAGE("PRAGMA_MESSAGE quoted")
#warning "#pragma warning quoted"
PRAGMA_WARNING(PRAGMA_WARNING unquoted)
PRAGMA_WARNING("PRAGMA_WARNING quoted")
ここでPRAGMA_WARNINGを使用します(これは修正する必要があります)
gccには #pragma warning
がありませんので、不特定のプラグマを警告します。
マイクロソフトが #warning
を追加するのではなく、gccが #pragma warning"
を追加することは疑わしい。
実際、私が知っているほとんどのコンパイラは、未知の#pragmaディレクティブを無視し、警告メッセージを出力します。したがって、最悪の場合でも、警告が表示されます。