2017-08-11 5 views
3

ich die folgende Funktion haben, und ich möchte Warnungen haben, wie man hat, wenn printf:C++ hinzufügen Compiler-Warnungen für falsche Verwendung von benutzerdefinierten Druck/log Funktion

void LoggingManager::log(int32_t logLevel, const char *p_str, ...) 
{ 
    va_list args; 
    va_start(args, p_str); 
    vsnprintf(s_LogginManagerBuffer, LOGGING_MANAGER_BUFFER_SIZE - 1, p_str, args); 
    va_end(args); 

    internalLog(s_LogginManagerBuffer); 
} 

Ich möchte Irgendwie habe ich Warnungen, wenn ich vergessen habe, ein Argument für eines der Token in der Format-Zeichenfolge hinzuzufügen. Auch Warnungen für zu viele (oder falsche Argumente) wären genial. Ich hatte kürzlich einige Abstürze, weil ich ein Argument in der Protokollierungsfunktion vergessen hatte.

Wenn es so nicht möglich ist, wie könnte ich meine Funktion umschreiben, Warnungen aber die gleiche Funktionalität haben?

+2

Bitte Markieren Sie nicht mit c, das ist kein gültiger c-Code. –

Antwort

4

Wenn Sie mit gcc/g ++/Klirren Sie das Format Attribut, wie auf this page verwenden können:

Format (Urbild, String-Index, first-to-check)

Das Attribut format gibt an, dass eine Funktion die Argumente printf, scanf, strftime oder strfmon style akzeptiert, die mit einer Formatzeichenfolge typgeprüft werden sollen. Zum Beispiel ist die Erklärung:

extern int my_printf (void *my_object, const char *my_format, ...) __attribute__ ((format (printf, 2, 3)));

bewirkt, dass der Compiler die Argumente Anrufe my_printf für die Übereinstimmung mit dem printf Stil Format-String-Argument my_format zu überprüfen.

Es spielt keine Rolle, ob der __attribute__ vor oder nach dem Funktionsprototyp ist.

Also in Ihrem Fall können Sie etwas tun:

class LoggingManager { 
    ... 
public: 
    void log(int32_t logLevel, const char *p_str, ...) __attribute__((format (printf, 3, 4))); 
    ... 
}; 

Beachten Sie, dass, weil es sich um eine Member-Funktion Sie für die implizite this Parameter übergeben Konto müssen. Die Formatzeichenfolge wäre also eigentlich das 3. Argument anstelle des 2. Arguments. (format (printf, 3, 4) statt format (printf, 2, 3))

Sehen Sie es Arbeit here.

+0

Beachten Sie, dass [Clang dies auch unterstützt] (https://clang.llvm.org/docs/AttributeReference.html#format-gnu-format). –

+0

@DanielH Danke! Meine Antwort wurde aktualisiert. – Kevin

+0

Danke! Das ist sehr schön und Bonuspunkte für die Verwendung in meiner Memberfunktion! :) – keyboard

0

Wenn Sie Visual Studio verwenden, können Sie SAL annotation_Printf_format_string_ Makro verwenden:

#include <sal.h> 

void log 
(
    int32_t         log_level 
, _In_z_ _Printf_format_string_ const char * psz_format 
, ... 
); 

Um Code portable Sie Format Attribut Makro und SAL-Makros Substitutionen definieren wollen, wenn nötig:

#if defined(__GNUC__) 
#define ATTRIBUTE_PRINTF(format_index, vargs_index) __attribute__((__format__ (__printf__, format_index, vargs_index))) 
#else 
#define ATTRIBUTE_PRINTF(format_index, vargs_index) 
#endif 

#if defined(_MSC_VER) 
#include <sal.h> 
#else 
#define _In_z_ 
#define _Printf_format_string_ 
#endif 

void log 
(
    int32_t         log_level 
, _In_z_ _Printf_format_string_ const char * psz_format 
, ... 
) ATTRIBUTE_PRINTF(2, 3); 
Verwandte Themen