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:28:08 GMT
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.













Mime
View raw message