On Thu, Sep 6, 2012 at 6:43 PM, Stefan Teleman <stefan.tele...@gmail.com> wrote:
> On Thu, Sep 6, 2012 at 4:02 PM, Martin Sebor <mse...@gmail.com> wrote:
>
>> Here's a thought: it's not pretty but how about having
>> the function initialize the facet? It already has a pointer
>> to the base class, so it could downcast it to std::numpunct
>> (or moneypunct, respectively), and assign the initial values
>> to the members. Would that work?
>
> I haven't looked at them in detail (yet) but a cursory look shows that
> they're both recursive for the successful case.

It's not going to work that way.

For one, __rw_get_numpunct() and __rw_get_moneypunct() are static
functions in the __rw namespace. Neither can access or modify the
std::numpunct<T> or std::moneypunct<T> data members directly, because
they are private.

Second, both __rw_get_numpunct() and __rw_get_moneypunct() are
recursive. Unless we want to start playing with
PTHREAD_MUTEX_RECURSIVE, which I'm not at all sure is supported on all
the platforms we support, we're not going to be able to solve the
thread-safety problem here (Linux supports it as
PTHREAD_MUTEX_RECURSIVE_NP, Solaris supports it
PTHREAD_MUTEX_RECURSIVE).

Third, both __rw_get_numpunct() and __rw_get_moneypunct() can return a
NULL pointer. This is bad, because it will cause a SEGV at string
assignment, during a call to either of the
std::numpunct<T>::grouping(), std::numpunct<T>::truename(), etc.
functions. We should fix this and throw an exception instead. The
Standard doesn't say that any of these functions can throw, but it
doesn't say they can't throw either. And both __rw_get_numpunct() and
__rw_get_moneypunct() throw already.

--Stefan

-- 
Stefan Teleman
KDE e.V.
stefan.tele...@gmail.com

Reply via email to