From: Masaya Tarui Date: 2012-01-30T09:05:07+09:00 Subject: [ruby-dev:45157] [ruby-trunk - Feature #5896] object representaion in rb_enc_vsprintf() Issue #5896 has been updated by Masaya Tarui. 警告については、gccの拡張ですしPRINTF_ARGSを諦めるのどうですか? 拡張した時点でprintf書式に合わないのはしようがないと思います。 ---------------------------------------- Feature #5896: object representaion in rb_enc_vsprintf() https://bugs.ruby-lang.org/issues/5896 Author: Nobuyoshi Nakada Status: Open Priority: Normal Assignee: Yukihiro Matsumoto Category: core Target version: 2.0.0 =begin (({rb_enc_vsprintf()}))で(({VALUE}))を受け付けるようにする拡張です。 文字列化したオブジェクトを含むメッセージを組み立てる場合、 (({StringValueCStr()}))や(({RSTRING_PTR()}))で得られるポインタを(({snprintf()}))などに渡 すというのが定番ですが、これはエンコーディングが保存されない、最適化に よって元の(({VALUE}))が消されてしまいdangling pointerになってしまう危険性があ る、などの問題があります。後者は、とくに(({rb_raise()}))のように(({NORETURN}))な関 数に渡すときには、tail-call最適化のために(({RB_GC_GUARD}))があっても安全とは 限りません。前者については今のところほとんど無視されている状態です。 これらの問題を解消するため、(({rb_enc_vsprintf}))(およびこれを使う関数全般)を (({VALUE}))自体を受けつけるように拡張すべきだと考えています。具体的な指定方法 としては、新しい変換指定子(%vなど)を追加することも考えましたが、gccは割 りと小賢しくチェックを入れてくれるので、警告がジャマになります。 小崎さんによると、Linux Kernelでも(({printk()}))に対する似たような要望は多かっ たらしく、(({%p}))で始まる複数文字の変換指定子というものが導入されているそう で、ソース[1]を見ると今ではが20個近くもあるようです。 [1] [[URL|http://lxr.free-electrons.com/source/lib/vsprintf.c#L1116]] Rubyではオブジェクト自身が文字列化メソッドを持っているため、それを使っ て変換するもの一つあれば充分です。なるべく被りそうにないものということ で、(({"%lo\v"}))あたりでよいのではないかと思っています。 以下のコードは、例として((%error.c%))にある(({rb_invalid_str()}))を変更したものです。 void rb_invalid_str(const char *str, const char *type) { VALUE s = rb_str_inspect(rb_str_new2(str)); rb_raise(rb_eArgError, "invalid value for %s: %"PRIsVALUE, type, s); } =end -- http://bugs.ruby-lang.org/