printf()関数と云へば、先づ頭に浮かぶのは可変変数と云ふ特徴でせう。
printf()関数のやうな可変変数は、どうすれば実現できるのでせう。
int型ではなくvoid型のprintf()もどき関数prf()を作成してみませう。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
void
prf (const char *format, ...)
{
va_list list;
va_start (list, format);
(void)vprintf (format, list);
va_end (list);
}
int
main (void)
{
prf ("%d: Hello!\n", 5);
return EXIT_SUCCESS;
}
可変引数の個数が分つてゐるときは、 formatではなくて、その個数をva_start()に指定できます。 え、型が違ふぢやないか、つて。 大丈夫です、va_start()はマクロ関数なので型確認はされません。 さて、ここからが上級講座。 GCCだけで使へるテクですが、prf()関数を次のやうに書き換えます。
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <syslog.h>
__attribute__((format(printf,1,2))) void
prf (const char *format, ...)
{
va_list list;
assert (NULL != format);
va_start (list, format);
(void)vprintf (format, list);
vsyslog (LOG_ERR, format, list);
va_end (list);
}
かうしておいてGCCのオプションとして-Wformat=2を指定すると、 自作のprf()関数も本物のprintf()関数と同様に、 フォーマットにリテラルではなく変数を指定して呼び出すと 警告がでるやうになります。 なぜリテラルを指定しなければならないか、については、 「printf()関数 その1」を御覧ください。