2014-06-14 20 views
5

Czy istnieje sposób na użycie makr do wymuszania ostrzeżeń i błędów podczas kompilowania?#warning i #error jako makro

Obecnie mam coś takiego:

#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 będzie traktować te makra jako ostrzeżeń/błędów i ten przykład nie będzie skompilować. Czy istnieje odpowiednik GCC i 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 
+0

Przeczytaj dokumentację, człowiek. –

+1

Naprawdę żałuję, że ludzie nie używają plików #pragma todo itp. Zajmują się kompilacją i nigdy nie są naprawieni – paulm

Odpowiedz

5

Tak, jest. Cytowanie GCC preprocessor documentation:

#pragma GCC warning 
#pragma GCC error 

#pragma GCC warning "message" powoduje preprocesora upomnienia diagnostyczny z tekstem „message”. Przesłanie zawarte w pragmie musi być pojedynczym ciągiem literalnym. Podobnie, #pragma GCC error "message" wydaje komunikat o błędzie. W przeciwieństwie do dyrektyw "#warning" i "#error", te pragmy mogą być osadzone w makrach preprocesora przy użyciu "_Pragma".

Testy pokazują, że te elementy działają również z klangiem.

Należy pamiętać, że nie trzeba umieszczać informacji o pliku i linii. Dyrektywa będzie wyświetlana jako zwykła diagnostyka, a wszystkie diagnostyki zawierają już informacje o pliku i linii.

W zależności od danego makra, inną opcją może być wymuszenie wywołania funkcji na funkcji oznaczonej atrybutami warning lub error. W przeciwieństwie do pragmy, atrybuty nie działają, jeśli wywołanie funkcji jest znane jako nieosiągalne (na przykład, ponieważ pojawia się w bloku if, gdzie warunek został wykryty w czasie kompilacji jako zawsze będący fałszywy), więc jeśli w tym przypadku chcesz ostrzeżenie lub błąd, który ma być stłumiony, mogą być bardziej odpowiednie.

+0

szukał teraz około 3 godzin, dzięki, że mi to pokazałeś :-) – nonsensation

+0

Używam przykładu z dokumentacji ' #pragma GCC ostrzeżenie "wiadomość" 'jednak otrzymuję następujące dane wyjściowe:' warning: ignoring #pragma GCC warning [-Wunknown-pragmas] | 'using gcc 4.7.1 – nonsensation

+2

@Serthy Są one dostępne począwszy od GCC 4.8. [Tutaj jest dokumentacja GCC 4.7] (https://gc.gnu.org/onlinedocs/gcc-4.7.4/cpp/Pragmas.html) i [tutaj jest dokumentacja GCC 4.8] (https: // gcc. gnu.org/onlinedocs/gcc-4.8.3/cpp/Pragmas.html), gdzie możesz zobaczyć, że zostały dodane. Atrybuty "warning" i "error" są dostępne dłużej, więc jeśli nie możesz dokonać aktualizacji do wersji GCC 4.8, możesz użyć ich zamiast nich. – hvd