qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Manuel Teira <mte...@tid.es>
Subject Re: qpid (cpp) on solaris + Sun Studio 12
Date Wed, 28 May 2008 08:45:53 GMT
Manuel Teira escribió:
> Alan Conway escribió:
>   
>> Manuel Teira wrote:
>>
>>     
>>> Some new info about this problem.
>>>
>>> I was not able to exactly reproduce the issue with an stanalone and
>>> meaninfull source, but have found a way to pass the compilation (other
>>> than commenting everything, of course). The problem, I think, is related
>>> with the std::lower_bound invocation, as shown before:
>>>
>>> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_algo.h", line 491:
>>> Information: Instantiating
>>> std::__lower_bound<qpid::Range<qpid::framing::SequenceNumber>*,
>>>                                  qpid::framing::SequenceNumber,
>>>                                  std::less<qpid::framing::SequenceNumber>,
>>>                                  long>
>>> (qpid::Range<qpid::framing::SequenceNumber>*,
>>> qpid::Range<qpid::framing::SequenceNumber>*,
>>> const qpid::framing::SequenceNumber&,
>>> std::less<qpid::framing::SequenceNumber>,
>>> long*).
>>>
>>> All the pain begins (I think) with the fact that the first template type
>>> (the iterator) is not valid to travel through the value type. And this
>>> is produced (I guess) by the call, in RangeSet<T>::addRange(const
>>> Range<T> &r) :
>>>
>>> typename Ranges::iterator i =
>>>        std::lower_bound(ranges.begin(), ranges.end(), r.begin());
>>>
>>> That way, we are passing two valid Range<T>::iterator types and a T
>>> value. changing that with:
>>>
>>> typename Ranges::iterator i = std::lower_bound(ranges.begin(),
>>> ranges.end(), r);
>>>
>>> it passes the compilation with the Sun Studio 12.
>>>
>>>       
>> Hum. Odd. The point of lower_bound(i,j,x) is to evaluate *i < x.
>> Range<T> has an operator< for T but not for Range<T> so I don't understand
>> how solaris is satisfying *i < x. when x is a Range<T>
>>
>> I tried the same thing myself and the GNU compiler didn't choke either so there
>> clearly is some conversion sequence that allows the < comparison but it doesn't
>> give the right answer because the RangeSet unit tests fail.
>>
>> HOWEVER: the simple and obvious step of adding:
>>
>>      bool operator<(const Range<T>& r) const { return end_ < r.begin_;
}
>>
>> to RangeSet makes the whole thing work beautifully so I bet it'll now build for
>> you - comitted in revision 660647
>>
>>     
> It does. Thanks a lot!
>
>   
>>> Perhaps the GNU compiler is able to instantiate a whole Range<T> from
>>> the r.begin() argument? However, the Range<T>::Range(const T &t)
>>> constructor is declared as explicit. So, I don't think that should be
>>> the problem
>>>
>>> As an outline, does it make sense to pass to std::lower_bound iterators
>>> not compatible with the value argument?
>>>
>>>       
>> Hah! No it does not. Turns out that one of the requirements on lower_bound is
>> that "ForwardIterator's value type is the same type as LessThanComparable."
>> I was under the mistaken impression that it was only required for *i < x to be
a
>> valid expression.
>>
>> So this whole thing is my goof, thanks for sticking with it.
>>
>>     
> You're welcome.
>   
>> Cheers,
>> Alan.
>> .
>>
>>
>>     
> Well, the compiling effort is progressing. I have a fresh
> libqpidcommon.so.0.1.0 but some other frightening errors arised in the
> broker side. Once again, I'm not able to figure out what is causing this
> one:
>
> ource='qpid/broker/SemanticState.cpp'
> object='qpid/broker/SemanticState.lo' libtool=yes \
> DEPDIR=.deps depmode=none /bin/bash ../build-aux/depcomp \
> /bin/bash ../libtool --tag=CXX    --mode=compile CC -m64 -mt
> -library=stlport4 -DHAVE_CONFIG_H -I. -Igen -I./gen
> -I/opt/dslap/contrib/include -c -o qpid/broker/SemanticState.lo
> qpid/broker/SemanticState.cpp
>  CC -m64 -mt -library=stlport4 -DHAVE_CONFIG_H -I. -Igen -I./gen
> -I/opt/dslap/contrib/include -c qpid/broker/SemanticState.cpp  -KPIC
> -DPIC -o qpid/broker/.libs/SemanticState.o
> "./qpid/sys/posix/Mutex.h", line 96: Warning (Anachronism): Formal
> argument 2 of type extern "C" void(*)() in call to pthread_once(_once*,
> extern "C" void(*)()) is being passed void(*)().
> "./qpid/sys/posix/Mutex.h", line 105: Warning (Anachronism): Formal
> argument 2 of type extern "C" void(*)() in call to pthread_once(_once*,
> extern "C" void(*)()) is being passed void(*)().
> "./qpid/sys/posix/Thread.h", line 67: Warning (Anachronism): Formal
> argument 3 of type extern "C" void*(*)(void*) in call to
> pthread_create(unsigned*, const _pthread_attr*, extern "C"
> void*(*)(void*), void*) is being passed void*(*)(void*).
> "./qpid/sys/posix/Thread.h", line 71: Warning (Anachronism): Formal
> argument 3 of type extern "C" void*(*)(void*) in call to
> pthread_create(unsigned*, const _pthread_attr*, extern "C"
> void*(*)(void*), void*) is being passed void*(*)(void*).
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_function.h", line 164:
> Error: Formal argument __r of type qpid::broker::DeliveryRecord& in call
> to std::mem_fun1_ref_t<void, qpid::broker::DeliveryRecord,
> qpid::broker::TransactionContext*>::operator()(qpid::broker::DeliveryRecord&,
> qpid::broker::TransactionContext*) const requires an lvalue.
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_algo.h", line 65:
> Where: While instantiating "std::binder2nd<std::mem_fun1_ref_t<void,
> qpid::broker::DeliveryRecord,
> qpid::broker::TransactionContext*>>::operator()(const
> qpid::broker::DeliveryRecord&) const".
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_algo.h", line 65:
> Where: Instantiated from non-template code.
> 1 Error(s) and 4 Warning(s) detected.
>
> The compiler is not giving me the offending source line, but just
> looking at the points of SemanticState.cpp where a DeliveryRecord method
> with a TransactionContext* argument is called using a bind2nd, has
> brought me to these two choices:
> line 418:      for_each(start, end,
> bind2nd(mem_fun_ref(&DeliveryRecord::dequeue), 0));
> line 684:      for_each(range.start, range.end,
> bind2nd(mem_fun_ref(&DeliveryRecord::accept), 0));
>
> Commenting out those two lines, leads to this other error:
>
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_function.h", line 164:
> Error: Formal argument __r of type qpid::broker::DeliveryRecord& in call
> to std::mem_fun1_ref_t<void, qpid::broker::DeliveryRecord,
> bool>::operator()(qpid::broker::DeliveryRecord&, bool) const requires an
> lvalue.
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_algo.h", line 65:
> Where: While instantiating "std::binder2nd<std::mem_fun1_ref_t<void,
> qpid::broker::DeliveryRecord, bool>>::operator()(const
> qpid::broker::DeliveryRecord&) const".
> "/opt/SUNWspro/prod/include/CC/stlport4/stl/_algo.h", line 65:
> Where: Instantiated from non-template code.
>
> Probably produced by line 639:
>
>     for_each(start, end, bind2nd(mem_fun_ref(&DeliveryRecord::release),
> setRedelivered));
>
> as it's the only method in DeliveryRecord accepting a bool as argument.
>
> I've read somewhere that std::for_each is not intended to modify the
> traversed sequence. But I'm not sure if "modifying" means the elements
> or the sequence itself. I've written this little test:
>
> #include <iostream>
> #include <vector>
> #include <algorithm>
> #include <functional>
>
> using namespace std;
>
> class Item {
> public:
>   Item(int i): m_i(i) {};
>   void setIndex(int i) { m_i = i; }
>   int getIndex() const { return m_i; }
>   void printTo(ostream *os) const { *os << "Item[" << m_i << "] ";
}
> private:
>   int m_i;
> };
>
> int main(int argc, char *argv[])
> {
>   vector<Item> items;
>   items.push_back(Item(0));
>   items.push_back(Item(1));
>   items.push_back(Item(2));
>   //for_each(items.begin(), items.end(),
> bind2nd(mem_fun_ref(&Item::setIndex), 0));
>   for_each(items.begin(), items.end(),
> bind2nd(mem_fun_ref(&Item::printTo), &cout));
> }
>
> Note the first for_each call, commented out. GNU g++ is able to compile
> and run that program without problem, even without commenting the first
> for_each call. So, it's able to call a non-const method on the iterated
> sequence. But that is not true for Sun Studio 12:
>
> -bash-3.00$ CC -o for_each for_each.cc
> "/opt/SUNWspro/prod/include/CC/Cstd/./functional", line 327: Error:
> Formal argument p of type Item& in call to std::mem_fun1_ref_t<void,
> Item, int>::operator()(Item&, int) const requires an lvalue.
> "/opt/SUNWspro/prod/include/CC/Cstd/./algorithm.cc", line 64:     Where:
> While instantiating "std::binder2nd<std::mem_fun1_ref_t<void, Item,
> int>>::operator()(const Item&) const".
> "/opt/SUNWspro/prod/include/CC/Cstd/./algorithm.cc", line 64:     Where:
> Instantiated from std::for_each<Item*,
> std::binder2nd<std::mem_fun1_ref_t<void, Item, int>>>(Item*, Item*,
> std::binder2nd<std::mem_fun1_ref_t<void, Item, int>>).
> "for_each.cc", line 24:     Where: Instantiated from non-template code.
> 1 Error(s) detected.
>
>
> Perhaps the problem is in the Sun CC STL binder2nd implementation:
>
> template <class _Operation>
> class binder2nd
>   : public unary_function<typename
> __BINARY_ARG(_Operation,first_argument_type),
>                           typename __BINARY_ARG(_Operation,result_type)> {
> protected:
>   _Operation _M_op;
>   typename _Operation::second_argument_type value;
> public:
>   binder2nd(const _Operation& __x,
>             const typename _Operation::second_argument_type& __y)
>       : _M_op(__x), value(__y) {}
>   typename _Operation::result_type
>   operator()(const typename _Operation::first_argument_type& __x) const {
>     return _M_op(__x, value);
>   }
> };
>
> The operator() has a const reference argument, and I think it's
> triggering the problem. Isn't this restricting binder2nd to only call
> const methods on the passed object?
>
> Confused greetings.
>
> --
> Manuel.
>   
It seems that this same problem is explained here:

http://www.progdoc.de/papers/adapter_binder/adapter_binder/adapter_binder.html



Mime
View raw message