2017-08-11 23 views
3

機能をログ/カスタム印刷の間違った使用法のためのコンパイラの警告を追加し、私はprintfの使用している場合1を持っているとして警告をしたいのです:C++私は、以下の機能を持っている

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); 
} 

私がしたいのですが書式文字列にトークンの1つの引数を追加することを忘れた場合は、何らかの警告が表示されます。あまりにも多く(または間違った引数)を持つための警告もすばらしいだろう。 私は最近、ロギング機能の引数を忘れるためにクラッシュしました。

このようにすることができない場合、私の機能を書き直して、警告を表示することはできますが、機能は同じですか?あなたがGCC/G ++ /打ち鳴らすあなたがthis pageに指定されているよう形式属性を使用することができます使用している場合は

+2

してくださいcでタグ付けしないでください。これは有効なcコードではありません。 –

答えて

4

形式(原型、文字列のインデックスを、最初にチェック)

format属性は、関数がフォーマット文字列に対してタイプチェックされるprintf、scanf、strftimeまたはstrfmonスタイルの引数を取ることを指定します。たとえば、宣言:

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

は、コンパイラはprintfのスタイルフォーマット文字列引数my​​_formatとの整合性を保つためにmy_printfの呼び出しで引数をチェックするために発生します。

__attribute__が関数プロトタイプの前でも後でもかまいません。これはあなたが渡された暗黙のthisパラメータを説明するために必要なメンバ関数であるため、その

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

注:

は、だからあなたの場合には、あなたがこのような何かを行うことができます。したがって、フォーマット文字列は実際には2番目の引数ではなく3番目の引数になります。 ( format (printf, 2, 3)の代わりに format (printf, 3, 4)

hereを参照してください。

+0

[Clangはこれもサポートしています](https://clang.llvm.org/docs/AttributeReference.html#format-gnu-format)に注意してください。 –

+0

@DanielHありがとう!私の答えを更新しました。 – Kevin

+0

ありがとう!これは、私のメンバー関数でそれを使用する方法を私に示すための非常に美しく、ボーナスポイントです! :) – keyboard

0

Visual Studioを使用している場合は、SAL annotation_Printf_format_string_マクロを使用することができます。

#include <sal.h> 

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

コードの移植を行うには、あなたはフォーマットを定義することもできますマクロ属性と、必要なときにSALは、置換をマクロ:

#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); 
関連する問題