web-dev-qa-db-ja.com

#warningプリプロセッサディレクティブの移植性

#warningディレクティブは標準ではないことを知っています[〜#〜] c [〜#〜]/C++ですが、gcc/g ++を含むいくつかのコンパイラがサポートしています。しかし、それをサポートしていない人にとっては、黙って無視するのでしょうか、それともコンパイルに失敗しますか?つまり、サポートしていないコンパイラーのビルドを壊すことなく、プロジェクトで安全に使用できますか?

52
jonner

コンパイラが#warningをサポートしていない場合、エラーが発生する可能性があります。 #pragmaとは異なり、プリプロセッサが理解できないディレクティブを無視することは推奨されません。

そうは言っても、私はさまざまな(かなり一般的な)プラットフォームでコンパイラを使用し、それらはすべて#warningをサポートしています。

30
Greg Hewgill

MSVCは次の構文を使用することに注意してください。

#pragma message( "ここに警告テキスト")

通常の#warning構文は致命的なエラーを生成します

 C1021:無効なプリプロセッサコマンド 'warning' 

そのため、これらのコンパイラには移植できません。

72
nolandda

コンパイルにコードブロックが含まれていなくても、#warningを認識しないコンパイラーから、少なくとも認識されないディレクティブ警告が表示される可能性があります。これはエラーとして扱われる場合とそうでない場合があります。コンパイラは合法的にそれをエラーとして扱うことができますが、多くはもっと緩いものになります。

#warningを提供するGCC/G ++以外のコンパイラを知っていますか(名前を付けてください)? [編集: Sun Solaris 10(Sparc)およびStudio 11 C/C++コンパイラは、どちらも#warningを受け入れます。]

3

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がないため、不特定のプラグマを警告します。

Microsoftが#pragma warning"を追加するのではなく、gccが#warningを追加することを疑います。

1
fantastory

Atmelプロセッサ用のコンパイラでこの問題が発生しました。また、未知の#warningトークンが原因でプリプロセッサエラーが発生しました。

残念なことに、解決策は、ソースツリー全体を変換して#pragmaと同等のものを使用し、gccを使用するとビルド動作が異なることを受け入れることであるように思われました。

1

実際、私が知っているほとんどのコンパイラは、未知の#pragmaディレクティブを無視し、警告メッセージを出力します。したがって、最悪の場合でも、警告が表示されます。

0