可変数の引数を取る関数をCで書いています。
size_t myprintf(char *fmt, ...);
ここまでは順調ですね。RightWay™を実行して、可変引数をとるバージョンと、をとる別のバージョンを作成するのが最善であると判断しましたva_list
。
size_t myprintf(char *fmt, ...);
size_t myvprintf(char *fmt, va_list args);
それほど難しいことではありません。ただし、2つの異なる関数my_vprintf()
に送信する必要がありますargs
(最初にsnprintf()
長さ0で必要な部屋の量を決定し、次にsprintf()
その量の部屋を割り当てた後に)。私はこれをで行いva_copy
ます。
size_t myvprintf(char *fmt, va_list args)
{
va_list args2;
va_copy(args, args2);
// do stuff with args2
va_end(args2);
// do more stuff with args
}
これはすべて問題なくダンディですが、C99の実装は少し不十分です。可能であれば、コードをC89でも動作させ、できるだけ多くのコンパイラーとプラットフォームで動作させたいと思います。私は現在#include <stddef.h>
、コードの後で、しかし前にこれを持っています:
#ifndef va_copy
# ifdef __va_copy
# define va_copy(a,b) __va_copy(a,b)
# else /* !__va_copy */
# define va_copy(a,b) ((a)=(b))
# endif /* __va_copy */
#endif /* va_copy */
それ((a)=(b))
は信頼できないので、多分使うべきだと思いますmemcpy()
が、これは「C99をサポートしていなければ、うまくいくといいのですが」というレベルにあります。 C99、恐れることはありません」(これが私が望むものです)。この制限を回避する良い方法はありますか?私はいくつかの解決策を見てきましたva_list
-1つの引数を食べて再帰する関数、2つを渡してva_list
2つの別々のコピーが作成されるなど-しかし私はそれらがどれほどうまくいくかわかりません(そして再帰的な解決策はうまくいきません電話をかけたいだけならvsnprintf()
、今、そうしますか?)
だから私はあなたに目を向けます、StackOverflowユーザー。C89との互換性を提供するために私ができることは他にありますか、それともユーザーはva_copy
それ__va_copy
を吸い込んで受け入れる必要がありますか?