Hi all,
I removed the implicit conversions from numbers to Strings, so now you
have to say "str + String(123)" instead of "str + 123". Similarly for
= and ==. This should make more explicit what's actually going on in
each case.
I also changed the implementation that allows you to write "if (s)"
from an operator bool() to an operator that returns a function
pointer. This avoids many of the complications caused by the
possibility of implicit conversion to a bool (e.g. "s + 123" would
give 124, because "s" would be automatically converted to true / 1).
It also allowed me to remove the additional operator+() friend
functions I had added, so now all concatenation with the + operator
should use the StringSumHelper and automatic temporaries again.
David
_______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
> I removed the implicit conversions from numbers to Strings, so now you
> have to say "str + String(123)" instead of "str + 123".
This will break the efficiency of concat() and the + operator.
For a StringSumHelper temporary object to grow in place efficiently (eg,
using realloc), the right hand side of the operator needs to be
converted on the stack. Those several overloaded functions were created
to avoid implicit constructors causing heap allocations in the common
case of a chain of + operators.
By requiring a constructor on the right hand side, an additional
allocation is made before each operator, which will typically
immediately follow the StringSumHelper's buffer on the heap. That
forces the realloc which grows StringSumHelper to allocate a completely
new buffer and move the entire temporary string. Each subsequent +
operator in the chain can't reuse any of the original allocations if
they're separated by the buffers created from those constructors (the
compiler calls all their destructors only after the entire expression is
used), so the result is pretty much a worst case memory allocation pattern.
I'm sorry to keep posting these breakage warnings, but maybe it's better
to know now rather than later?
> Similarly for
> = and ==. This should make more explicit what's actually going on in
> each case.
It's definitely more explicit, but does that also translate to more usable?
> I also changed the implementation that allows you to write "if (s)"
> from an operator bool() to an operator that returns a function
> pointer. This avoids many of the complications caused by the
> possibility of implicit conversion to a bool (e.g. "s + 123" would
> give 124, because "s" would be automatically converted to true / 1).
> It also allowed me to remove the additional operator+() friend
> functions I had added, so now all concatenation with the + operator
> should use the StringSumHelper and automatic temporaries again.
>
> David
>
> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.
Alright, I restored the String operator+() for built-in types, so you
can say "str + 123" again. The implementation should be effectively
as it was in your original rewrite, Paul, as the new "if (s)"
implementation means that there's no need for extra
(non-StringSumHelper) operator+() functions.
I'd rather not provide methods for comparing strings and numbers,
though, because it's not clear whether the comparison should be done
as a string or a number. For example, it's not clear what this result
should be: String("123") > 56.
Right now, you also can't say "s = 123;", although I'm more ambivalent
about this. Since we do an implicit number to string conversion with
operator+(), it doesn't seem unreasonable to do one with operator=().
On the other hand, "s = String(123);" is not so bad. Any thoughts?
David
On Sun, Mar 27, 2011 at 12:53 PM, Paul Stoffregen <> wrote:
>
>> I removed the implicit conversions from numbers to Strings, so now you
>> have to say "str + String(123)" instead of "str + 123".
>
>
> This will break the efficiency of concat() and the + operator.
>
> For a StringSumHelper temporary object to grow in place efficiently (eg,
> using realloc), the right hand side of the operator needs to be converted on
> the stack. Those several overloaded functions were created to avoid
> implicit constructors causing heap allocations in the common case of a chain
> of + operators.
>
> By requiring a constructor on the right hand side, an additional allocation
> is made before each operator, which will typically immediately follow the
> StringSumHelper's buffer on the heap. That forces the realloc which grows
> StringSumHelper to allocate a completely new buffer and move the entire
> temporary string. Each subsequent + operator in the chain can't reuse any
> of the original allocations if they're separated by the buffers created from
> those constructors (the compiler calls all their destructors only after the
> entire expression is used), so the result is pretty much a worst case memory
> allocation pattern.
>
> I'm sorry to keep posting these breakage warnings, but maybe it's better to
> know now rather than later?
>
>
>> Similarly for
>> = and ==. This should make more explicit what's actually going on in
>> each case.
>
> It's definitely more explicit, but does that also translate to more usable?
>
>
>> I also changed the implementation that allows you to write "if (s)"
>> from an operator bool() to an operator that returns a function
>> pointer. This avoids many of the complications caused by the
>> possibility of implicit conversion to a bool (e.g. "s + 123" would
>> give 124, because "s" would be automatically converted to true / 1).
>> It also allowed me to remove the additional operator+() friend
>> functions I had added, so now all concatenation with the + operator
>> should use the StringSumHelper and automatic temporaries again.
>>
>> David
>>
>> _______________________________________________
___________________________________________________
Posted on the Developers mailing list. Go to http://arduino.cc/mailman/listinfo/developers_arduino.cc to subscribe.