2014-06-14 2 views
5

C'è un modo per avere macro per forzare avvertimenti ed errori durante la compilazione?#warning e #error come Macro

Al momento ho qualcosa di simile:

#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 sarà il trattamento di queste macro come avvertimenti/errori e questo esempio non verrà compilato. Esiste un equivalente per GCC e 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

Leggi la documentazione, amico. –

+1

Vorrei davvero che le persone non usassero #pragma todo's ecc. Ingombrano l'output della build e non vengono mai corretti – paulm

risposta

5

Sì, c'è. Citando il GCC preprocessor documentation:

#pragma GCC warning 
#pragma GCC error 

#pragma GCC warning "message" fa sì che il preprocessore di emettere una diagnosi di avviso con il testo ‘message’. Il messaggio contenuto nel pragma deve essere un singolo stringa letterale. Allo stesso modo, #pragma GCC error "message" emette un messaggio di errore. A differenza delle direttive "#warning" e "#error", queste direttive possono essere incorporate nelle macro del preprocessore usando "_Pragma".

I test mostrano che questi funzionano anche con clang.

Nota che non è necessario incorporare il file e le informazioni sulla linea. La direttiva verrà emessa come una normale diagnostica e tutta la diagnostica include già le informazioni su file e linea.

A seconda della specifica macro in questione, un'altra opzione può essere quella di forzare una chiamata di funzione a una funzione contrassegnata dagli attributi warning o error. A differenza dei pragma, gli attributi non hanno alcun effetto se la chiamata alla funzione è conosciuta come irraggiungibile (ad esempio perché appare in un blocco if in cui la condizione è stata rilevata in fase di compilazione come sempre falsa), quindi se in quel caso si desidera l'avvertimento o l'errore da sopprimere, possono essere più appropriati.

+0

cercavo 3 ore come ora, grazie che me l'hai mostrato :-) – nonsensation

+0

Uso l'esempio dalla documentazione ' #pragma Avviso GCC "messaggio" 'tuttavia ottengo il seguente risultato:' avviso: ignorando #pragma avviso GCC [-Principazioni non note] | 'utilizzando gcc 4.7.1 – nonsensation

+2

@Serthy Sono disponibili a partire da GCC 4.8. [Ecco la documentazione di GCC 4.7] (https://gcc.gnu.org/onlinedocs/gcc-4.7.4/cpp/Pragmas.html), e [ecco la documentazione di GCC 4.8] (https: // gcc. gnu.org/onlinedocs/gcc-4.8.3/cpp/Pragmas.html) dove puoi vedere che sono stati aggiunti. Gli attributi 'warning' e' error' sono stati disponibili più a lungo, quindi se non è possibile eseguire l'aggiornamento a GCC 4.8, è preferibile utilizzarli. – hvd