Feature #5896
closedobject representation in rb_enc_vsprintf()
Description
=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
Updated by kosaki (Motohiro KOSAKI) almost 13 years ago
基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?
\StringValue(v);
rb_raise("%p")
と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします
Updated by nobu (Nobuyoshi Nakada) almost 13 years ago
Motohiro KOSAKI wrote:
基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?
\StringValue(v);
rb_raise("%p")と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします
VALUEがunsigned longだったりunsigned long longだったりするので、できる
限り警告を避けようと思うとPRIsVALUEは避けようがないんですよねぇ。
ほとんど使われてそうにない%iのほうが%oよりいいかも、という気もしますが。
Updated by nobu (Nobuyoshi Nakada) almost 13 years ago
- Tracker changed from Bug to Feature
Updated by tarui (Masaya Tarui) almost 13 years ago
警告については、gccの拡張ですしPRINTF_ARGSを諦めるのどうですか?
拡張した時点でprintf書式に合わないのはしようがないと思います。
Updated by tarui (Masaya Tarui) almost 13 years ago
redmineにコメント書いたんですが、MLと連携されてないように見えるので
こちらにも投稿しときます。
警告については、gccの拡張ですしPRINTF_ARGSを諦めるのどうですか?
拡張した時点でprintf書式に合わないのはしようがないと思います。
--
樽家昌也(Masaya TARUI)
No Tool,No Life.
2012年1月16日22:00 Nobuyoshi Nakada nobu@ruby-lang.org:
Issue #5896 has been updated by Nobuyoshi Nakada.
Motohiro KOSAKI wrote:
基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?
\StringValue(v);
rb_raise("%p")と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします
VALUEがunsigned longだったりunsigned long longだったりするので、できる
限り警告を避けようと思うとPRIsVALUEは避けようがないんですよねぇ。ほとんど使われてそうにない%iのほうが%oよりいいかも、という気もしますが。
Bug #5896: object representaion in rb_enc_vsprintf()
https://bugs.ruby-lang.org/issues/5896
Updated by nobu (Nobuyoshi Nakada) almost 13 years ago
- Subject changed from object representaion in rb_enc_vsprintf() to object representation in rb_enc_vsprintf()
Updated by shyouhei (Shyouhei Urabe) almost 13 years ago
- Status changed from Open to Assigned
Updated by nobu (Nobuyoshi Nakada) over 12 years ago
- % Done changed from 0 to 100
- Status changed from Assigned to Closed