Semantics of toString
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Thu Nov 12 13:54:13 PST 2009
Steven Schveighoffer wrote:
> On Thu, 12 Nov 2009 16:19:39 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>
>> Steven Schveighoffer wrote:
>>> On Thu, 12 Nov 2009 14:40:12 -0500, Andrei Alexandrescu
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> Steven Schveighoffer wrote:
>>>>> On Thu, 12 Nov 2009 13:46:08 -0500, Andrei Alexandrescu
>>>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>>>
>>>>>>> From my C++ book, it appears to only use virtual inheritance.
>>>>>>> I don't know enough about virtual inheritance to know how that
>>>>>>> changes function calls.
>>>>>>> As far as virtual functions, only the destructor is virtual, so
>>>>>>> there is no issue there.
>>>>>>
>>>>>> You're right, but there is an issue because as far as I can recall
>>>>>> these functions' implementation do end up calling a virtual
>>>>>> function per char; that might be streambuf.overflow. I'm not keen
>>>>>> on investigating this any further, but I'd be grateful if you
>>>>>> shared any related knowledge.
>>>>> Yep, you are right. It appears the reason they do this is so the
>>>>> conversion to the appropriate width can be done per character (and
>>>>> is a no-op for char).
>>>>>
>>>>>> At the end of the day, there seem to be violent agreement that we
>>>>>> don't want one virtual call per character or one delegate call per
>>>>>> character.
>>>>> After running my tests, it appears the virtual call vs. delegate
>>>>> is so negligible, and the virtual call vs. direct call is only
>>>>> slightly less negligible, I think the virtualness may not matter.
>>>>> However, I think avoiding one *call* per character is a worthy goal.
>>>>> This doesn't mean I change my mind :) I still think there is
>>>>> little benefit to having to conjure up an entire object just to
>>>>> convert something to a string vs. writing a simple inner function.
>>>>> One way to find out is to support only char[], and see who
>>>>> complains :) It'd be much easier to go from supporting char[] to
>>>>> supporting all the widths than going from supporting all to just one.
>>>>
>>>> One problem I just realized is that, if we e.g. offer only put(in
>>>> char[]) or a delegate to that effect, we make it impossible to
>>>> output one character efficiently. The (&c)[0 .. 1] trick will not
>>>> work in safe mode. You'd have to allocate a one-element array
>>>> dynamically.
>>> char[1] buf;
>>> buf[0] = c;
>>> put(buf);
>>
>> This would not compile in SafeD.
>
> :O
>
> Why not? I would expect that using a local buffer would be the main way
> for converting non-string things to strings, or to avoid calling the
> delegate/vfunction lots of times.
Well a stack-allocated buffer is stack-allocated, and passing a slice
out of it to a function may cause the function to escape the slice.
> i.e. if I want to output an integer i:
>
>
> if(i == 0) put("0");
> else
> {
> char[20] buf;
> int idx = buf.length - 1;
> while(i != 0)
> {
> buf[idx] = i % 10;
> --idx;
> i /= 10;
> }
> put(buf[idx..$]); // no compily in SafeD???
> }
>
> Do I have to allocate a heap buffer in SafeD?
I'm afraid so. Unless of course you have a put(dchar) routine handy :o).
>>>> Also, many OSs adopted UTF-16 as their standard format. It may be
>>>> wise to design for compatibility.
>>> So you want toString's to look like this?
>>> version(utf16isdefault)
>>> {
>>> textobj.put("Array: "w);
>>> ...
>>> }
>>> else
>>> {
>>> textobj.put("Array: ");
>>> ...
>>> }
>>> -Steve
>>
>>
>> I was just thinking of offering an interface that offers utf8 and
>> utf16 and utf32.
>
> Yes, and your explaination for this is because many OSes adopt UTF-16 as
> their standard format. My expectation is that the outputter will
> convert to the required OS format anyways, regardless of what you pass
> it, so why should we write code to cater to what the OS wants? I'd like
> to write string-handling code once and be done with it, not try to
> optimize my toString functions so that they use the "right" methods for
> the current OS. I asserted that the only reason you want to use the
> functions other than the char[] version is in the case where your data
> is *stored* as wchar[] or dchar[]. Otherwise, it makes no sense to do
> the conversion because the outputter already does it for you. So the
> question becomes, how often do you need to output data that's already in
> dchar[] or wchar[] format, and is it worth passing around a list of
> functions just in case you need that, or should you just call a
> conversion routine the few times you need it?
>
> Let's not forget that this is mainly for debugging...
If it's mainly for debugging maybe it's not worth spending time on.
Andrei
More information about the Digitalmars-d
mailing list