2017-04-16 9 views
1

私はアップルのUnified Loggingを初めて使用していて、ある程度の成功を収めました。しかし、私はそれを提案された%{timeval}.*Pカスタムフォーマット指定子で動作させることはできません。os_log timeval形式のClangエラー

私の最初の試みのようなものだった:

struct timeval some_time; 
// ... populate `some_time` 
os_log_info(OS_LOG_DEFAULT, "a thing happened at %{timeval}.*P", some_time); 

しかし、打ち鳴らすには、エラーを報告:field precision should have type 'int', but argument has type 'struct timeval'

私は、clangがos_logの書式設定ルールを理解していないと思っています。もし私がclangを持っている方法を理解できれば、clang diagnostic pushなどでエラーを抑えることができます。基本的なマクロOS_LOG_CALL_WITH_FORMATが運を使わずにそれをしようとしているようです。

timevalフォーマット指定子を誤って使用していますか?

これはXcode 8.3.1で、以前のバージョンのXcodeは試していません。

答えて

1

timevalのフォーマット指定子は、documentationに従って正しいです。明らかに、ClangはXcode 8.3.2以降の新しいフォーマット文字列を認識していません。 #clang diagnostic ignored "-Wformat"で無効にするのは無駄な試みです。

Format specifier documentation

どうやらこれに対する解決策はありません - その間にこれらの新しい空想の書式指定子を使用しないように。具体的には、末尾が.*Pの書式文字列を使用しないでください。しかし、dの形式が機能しているようです。

0

TL; DR

の作業コード

os_log_info(OS_LOG_DEFAULT, "a thing happened at %{timeval}.16P", &some_time); 

OR

os_log_info(OS_LOG_DEFAULT, "a thing happened at %{timeval}.*P", (int)sizeof(some_time), &some_time); 

は、ここでの問題は、フォーマット定義にワイルドカード(*)はint型の略ということです。実際には%{timeval}。* Pは2つの引数を受け取ります:intとtimeval構造体へのポインタ。

残念なことに、これは非常に詳細に文書化されており、Apple Sample Codeでもos_logの使用法にはこの例はありません。

これまでのところ、例を見る最も良い方法は、LLVMソースコードのテストを調べることです。 format-strings-oslog.m

__builtin_os_log_format(buf, "%d", i); 
__builtin_os_log_format(buf, "%P", p); // expected-warning {{using '%P' format specifier without precision}} 
__builtin_os_log_format(buf, "%.10P", p); 
__builtin_os_log_format(buf, "%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}} 
__builtin_os_log_format(buf, "%.*P", i, p); 
__builtin_os_log_format(buf, "%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}} 
関連する問題