#предупреждение и #ошибка как макрос


Есть ли способ использовать макросы для принудительного вызова предупреждений и ошибок при компиляции?

В настоящее время у меня есть что-то вроде этого:

#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 6

1 ответ:

Да, есть. Цитируя документацию препроцессора GCC :

#pragma GCC warning
#pragma GCC error

#pragma GCC warning "message" заставляет препроцессор выдавать диагностическое предупреждение с текстом " message". Сообщение, содержащееся в pragma, должно быть одним строковым литералом. Аналогично, #pragma GCC error "message" выдает сообщение об ошибке. В отличие от директив "#warning " и " #error", эти прагмы могут быть встроены в макросы препроцессора с помощью " _Pragma".

Тестирование показывает, что они также работают с clang.

Примечание что вам не нужно вставлять информацию о файле и строке. Директива будет выводиться как обычная диагностика, и все диагностики уже включают информацию о файле и строке.

В зависимости от конкретного макроса, о котором идет речь, другим вариантом может быть принудительный вызов функции, помеченной атрибутами warning или error. В отличие от прагм, атрибуты не имеют никакого эффекта, если известно, что вызов функции недоступен (например, потому что он появляется в блоке if, где условие было обнаружено во время компиляции как всегда ложное), поэтому, если в этом случае вы хотите, чтобы предупреждение или ошибка были подавлены, они могут быть более подходящими.