#предупреждение и #ошибка как макрос
Есть ли способ использовать макросы для принудительного вызова предупреждений и ошибок при компиляции?
В настоящее время у меня есть что-то вроде этого:
#if defined( __clang__ )
# define PRAGMA( x ) _Pragma( #x )
#elif defined( __GNUC__ )
# define PRAGMA( x ) _Pragma( #x )
#elif defined( _MSC_VER )
# define PRAGMA( x ) __pragma( x )
#endif
#define STRINGISIZE( str ) #str
#define STR( str ) STRINGISIZE( str )
#define LINE STR( __LINE__ )
#define FILE __FILE__
#define FILE_LINE __FILE__ "(" LINE ")"
#define INFO( info , msg )
PRAGMA( message( FILE_LINE ": " #info ": " msg ) )
#define MESSAGE( m ) INFO( msg , m )
#define WARNING( w ) INFO( warning , w )
#define ERROR( e ) INFO( error , e )
#define TODO( t ) INFO( TODO , t )
int main()
{
MESSAGE( "MSG" )
TODO( "TODO" )
WARNING( "WARN" )
ERROR( "ERROR" )
}
Visual Studio 2013 будет рассматривать эти макросы как предупреждения / ошибки, и этот пример не будет компилироваться. Есть ли эквивалент для GCC и Clang?
#if defined( _MSC_VER )
#define INFO( info , msg )
PRAGMA( message( FILE_LINE ": " #info ": " msg ) )
#define MESSAGE( m ) INFO( info , m )
#define WARNING( w ) INFO( warning , w )
#define ERROR( e ) INFO( error , e )
#define TODO( t ) INFO( todo t )
#elif defined( __GNUC__ ) || defined( __clang__ )
#define INFO( info , msg )
PRAGMA( #info " : " #msg ) )
#define MESSAGE( m ) INFO( info , m )
#define WARNING( w ) INFO( GCC warning , w )
#define ERROR( e ) INFO( GCC error , e )
#define TODO( t ) INFO( , "todo" t )
#endif
1 ответ:
Да, есть. Цитируя документацию препроцессора GCC :
Тестирование показывает, что они также работают с clang.#pragma GCC warning #pragma GCC error
#pragma GCC warning "message"
заставляет препроцессор выдавать диагностическое предупреждение с текстом "message
". Сообщение, содержащееся в pragma, должно быть одним строковым литералом. Аналогично,#pragma GCC error "message"
выдает сообщение об ошибке. В отличие от директив "#warning
" и "#error
", эти прагмы могут быть встроены в макросы препроцессора с помощью "_Pragma
".Примечание что вам не нужно вставлять информацию о файле и строке. Директива будет выводиться как обычная диагностика, и все диагностики уже включают информацию о файле и строке.
В зависимости от конкретного макроса, о котором идет речь, другим вариантом может быть принудительный вызов функции, помеченной атрибутами
warning
илиerror
. В отличие от прагм, атрибуты не имеют никакого эффекта, если известно, что вызов функции недоступен (например, потому что он появляется в блокеif
, где условие было обнаружено во время компиляции как всегда ложное), поэтому, если в этом случае вы хотите, чтобы предупреждение или ошибка были подавлены, они могут быть более подходящими.