Post
Topic
Board Development & Technical Discussion
Re: Ported Bitcoin (and Litecoin) 0.8.6 to VS2012 (32 and 64 bit) and Qt5
by
old c coder
on 16/02/2014, 02:56:18 UTC
Hi Claire and other C++ experts,

Well, bitcointalk.org blew up taking the first version of this message into
oblivion, so I am reconstructing it as best I can.  I keep forgetting not to
compose in the window provided:(

Anyway, I downloaded the bitcoinqtmsvc2012-32138.zip version of 0.8.6
from codeplex, and my VC++ compiler has some "issues" with the  language in
regards the vector, among other things.

Looking at
http://msdn.microsoft.com/en-us/library/k449z507%28v=vs.80%29.aspx
for 2005 and
http://msdn.microsoft.com/en-us/library/9xd04bzs%28v=vs.110%29.aspx
for 2012,

notice that the data() method of vector does exist in 2005. 
Nor in 2008, it only "appeared" in 2010 and later versions!  So if one chooses
to not use &vch[0] and can't use vch.data(), could one use
&vch.at(0) or &(*vch.begin())?  Of course, one reads that
"unspecified" behavior results if there isn't (enough) data there!?  This
makes one wonder about the EvalScript() function is script.cpp

Also in serialize.h, an insert(..) method of CDataStream:
Code:
#ifndef _MSC_VER
    void insert(iterator it, std::vector::const_iterator first,
                                    std::vector::const_iterator last)
    {
        assert(last - first >= 0);
        if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
        {
            // special case for inserting at the front when there's room
            nReadPos -= (last - first);
            memcpy(&vch[nReadPos], &first[0], last - first);
        }
        else
            vch.insert(it, first, last);
    }
#endif
that you "removed" from VC++ 2012's view, happens to be the one that VC++ 2005
want's to use!  If I leave it as is, I get:
Code:
Compiling...
main.cpp
...\src\wallet.h(864) : error C2664:
'void CDataStream::insert(CDataStream::iterator,CDataStream::size_type,const char &)' :
cannot convert parameter 2 from 'std::_Vector_const_iterator<_Ty,_Alloc>' to
'CDataStream::size_type'
        with
        [
            _Ty=char,
            _Alloc=std::allocator
        ]
        No user-defined-conversion operator available that can perform this conversion,
or the operator cannot be called

Build Time 0:08
Build log was saved at "file://...\Release\BuildLog.htm"
Bitcoin086CduS - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Finally, in main.cpp, the
std::set setBlockIndexValid;
// may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS,
// and must contain those who aren't failed


compiles the same whether it is std::set<.. or ::set<.. or
set<.. for me. But since, in release mode, some arcane switches are different,
and the set has its erase() method called,  I get the compiler error:
Code:
Compiling...
main.cpp
D:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1174) : error C3848:
expression having type 'const CBlockIndexWorkComparator' would lose some
const-volatile qualifiers in order to call 'bool CBlockIndexWorkComparator::operator ()
(CBlockIndex *,CBlockIndex *)'
        D:\Program Files\Microsoft Visual Studio 8\VC\include\xtree(1169) :
        while compiling class template member function 'std::_Tree_nod<_Traits>::_Node
        *std::_Tree<_Traits>::_Lbound(CBlockIndex *const &) const'
        with
        [
            _Traits=std::_Tset_traits                                                    std::allocator,false>
        ]
        D:\Program Files\Microsoft Visual Studio 8\VC\include\set(69) :
        see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
        with
        [
            _Traits=std::_Tset_traits                                                    std::allocator,false>
        ]
        .\src\main.cpp(59) : see reference to class template instantiation 'std::set<_Kty,_Pr>'
        being compiled
        with
        [
            _Kty=CBlockIndex *,
            _Pr=CBlockIndexWorkComparator
        ]
Build Time 0:15
Build log was saved at "file://...\Release\BuildLog.htm"
Bitcoin086CduS - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

A cure i have is to change CBlockIndexWorkComparator in main.h to:
Code:
struct CBlockIndexWorkComparator
{
#ifdef _MSC_VER
    bool operator()(CBlockIndex *pa, CBlockIndex *pb) const
#else
    bool operator()(CBlockIndex *pa, CBlockIndex *pb)
#endif
    {
        if (pa->nChainWork > pb->nChainWork) return false;
        if (pa->nChainWork < pb->nChainWork) return true;

        if (pa->GetBlockHash() < pb->GetBlockHash()) return false;
        if (pa->GetBlockHash() > pb->GetBlockHash()) return true;

        return false; // identical blocks
    }
};

I can finally compile a release version without errors!  I don't know if
this is "kosher", but it looks OK to me?  Any comments?

Does anyone else have similar experiences?

In the words of Blaise Pascal:
I would have written a shorter letter, but I did not have the time.
Provincial Letters: Letter XVI, 4 December, 1656.

Ron