Boost logo

Boost :

From: Jesse Jones (jesjones_at_[hidden])
Date: 2000-10-22 17:29:48


>
>>Right, there's one trivial error (is_POD needs a const int
>>specialization) and a more serious one where I try to get the value_type
>>using iterator_traits (because int* const is not a valid iterator type).
>
>Again there are sublties here: is_POD<const int> is deliberately false,
>otherwise you may find yourself memcpy'ing over a const array of int's. In
>this context we are saying that const int is not a POD because it is not
>trivially assignable.

I don't see now why I thought I needed a const int specialization. :-)
But anyway I think you're right.

>>Yes. :-) Why wouldn't it? You're explicitly telling the compiler to load
>>the pointer whenever it has to access it and save it whenever it is
>>modified. It seems to me that the compiler can do this easily enough with
>>the element by element version and with the memcpy version.
>
>I realised afterwards that copy was a bad example, consider:

Ahh, good. I thought you were setting me up. :-)

>extern const volatile int vi;
>
>int a[3];
>
>std::fill(a, a+3, vi);
>
>Would you expect a[0] to have the same value as a[2]? If so you're likely
>to be surprised (remember that volatile qualified types may be changed by
>events outside your programs control).

Check.

>Now imagine that fill was implemented using a block fill for integer types
>(load value once and then "rep stosd [addr]"), in this case the effect will
>be different from the "assign one at a time" version, and it's not clear
>which if either of these is correct.

I'm not sure the user can assume anything about how often vi is read
from. Even with a pure C++ implementation you can get different results:

template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value)
{
    typedef std::iterator_traits<ForwardIterator>::value_type T0;

    T0 v = value;
   
    for (; first != last; ++first)
        *first = v;
}

Of course, this is a rather silly implementation but something like this
may actually happen with a more complex algorithm.

In general I'd like to make these functions simpler and more intuitive
and rely on the compiler to catch errors. For example, I think is_pointer
should return true for int* const and rely on a compile time constraint
or a compiler error if the code attempts to, say, increment the pointer.
In those rare(?) cases where this would lead to erroneous dispatching
you'd have to test for and/or strip the cv-qualifiers.

  -- Jesse


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk