Переносимость директивы препроцессора #warning

Я знаю, что директива #warning не является стандартной C/ C++, но ее поддерживают несколько компиляторов, включая gcc/g++. Но для тех, кто не поддерживает это, они молча проигнорируют это, или это приведет к ошибке компиляции? Другими словами, могу ли я безопасно использовать его в своем проекте, не нарушая сборку для компиляторов, которые его не поддерживают?

6 ответов

Решение

Вполне вероятно, что если компилятор не поддерживает #warning, он выдаст ошибку. В отличие от #pragma, не рекомендуется, чтобы препроцессор игнорировал директивы, которые он не понимает.

Сказав это, я использовал компиляторы на различных (достаточно распространенных) платформах, и все они поддерживают #warning.

Следует отметить, что MSVC использует синтаксис:

#pragma message ("ваш текст предупреждения здесь")

Обычный синтаксис #warning генерирует фатальную ошибку

C1021: недопустимая команда препроцессора 'warning'

так что это не переносимо для этих компиляторов.

Скорее всего, вы получите по крайней мере предупреждение о нераспознанной директиве от компиляторов, которые не распознают #warning, даже если блок кода не включен в вашу компиляцию. Это может или не может рассматриваться как ошибка - компилятор может на законных основаниях рассматривать ее как ошибку, но многие из них будут более слабыми.

Знаете ли вы (можете ли вы назвать) компилятор, отличный от GCC/G++, который обеспечивает #warning? [Под редакцией: Sun Solaris 10 (Sparc) и компиляторы Studio 11 C/C++ оба принимают #warning.]

При переходе от 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(это нужно исправить)

К сожалению нет #pragma warning в gcc, поэтому он предупреждает неопределенную прагму.

Я сомневаюсь что gcc добавит #pragma warning" а не добавление в майкрософт #warning,

Однажды у меня была эта проблема с компилятором для процессора Atmel. И он генерировал ошибки препроцессора из-за неизвестного токена #warning.

К сожалению, решение, по-видимому, заключается в том, чтобы преобразовать все исходное дерево, чтобы использовать эквивалент #pragma, и признать, что поведение сборки будет отличаться при использовании gcc.

На самом деле большинство известных мне компиляторов игнорируют неизвестные директивы #pragma и выдают предупреждающее сообщение - так что в худшем случае вы все равно получите предупреждение.

Другие вопросы по тегам