epics-base / pvDataCPP

pvDataCPP is an EPICS V4 C++ module
https://epics-base.github.io/pvDataCPP/
Other
6 stars 16 forks source link

shared_vector begin()/end()==NULL offends MSVC #50

Closed mdavidsaver closed 5 years ago

mdavidsaver commented 6 years ago

It seems that the MSVC implementation of some STL requires that iterators never be NULL. This triggers an issue as shared_vector<> uses raw pointers as iterators, and gives NULL for an empty array.

@MarkRivers reports that this trigger copious assertion dialogs.

    testSerialization.exe!std::_Debug_message(const wchar_t * message=0x000000013f813048, const wchar_t * file=0x000000013f813080, unsigned int line=3049)  Line 15 C++
    testSerialization.exe!std::_Debug_pointer<unsigned char>(const unsigned char * _First=0x0000000000000000, const wchar_t * _File=0x000000013f813080, unsigned int _Line=3049)  Line 692  C++
    testSerialization.exe!std::equal<unsigned char const * __ptr64,unsigned char const * __ptr64>(const unsigned char * _First1=0x0000000000000000, const unsigned char * _Last1=0x0000000000000000, const unsigned char * _First2=0x0000000000000000)  Line 3051   C++
    testSerialization.exe!epics::pvData::`anonymous namespace'::compareArray<unsigned char>(const epics::pvData::PVValueArray<unsigned char> * left=0x000000000028ade0, const epics::pvData::PVValueArray<unsigned char> * right=0x00000000002889d0)  Line 159 + 0x4c bytes C++
    testSerialization.exe!epics::pvData::`anonymous namespace'::compareField(const epics::pvData::PVScalarArray * left=0x000000000028ade0, const epics::pvData::PVScalarArray * right=0x00000000002889d0)  Line 202 + 0x15 bytes    C++
    testSerialization.exe!epics::pvData::operator==(const epics::pvData::PVField & left={...}, const epics::pvData::PVField & right={...})  Line 339 + 0xf bytes    C++
    testSerialization.exe!`anonymous namespace'::testEquals()  Line 162 + 0x35 bytes    C++
    testSerialization.exe!main(int __formal=1, int __formal=1)  Line 875    C++
    testSerialization.exe!__tmainCRTStartup()  Line 278 + 0x19 bytes    C
    testSerialization.exe!mainCRTStartup()  Line 189    C
    kernel32.dll!00000000775259cd()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!000000007775a561()    

In this instance std::equal() asserts that the third argument is not NULL.

MarkRivers commented 6 years ago

Do you understand why we only have a problem on windows-x64-static, and not windows-x64?

mdavidsaver commented 6 years ago

shared_ptr<> is not consistent about zero length arrays vs. empty array. So:

shared_ptr X; shared_ptr Y(0);

behave differently.

mdavidsaver commented 6 years ago

Do you understand why we only have a problem on windows-x64-static, and not windows-x64?

It's probably a question of:

#ifdef _DEBUG
MarkRivers commented 6 years ago

It's probably a question of:

#ifdef _DEBUG

This is correct. In CONFIG_SITE.Common.windows-x64-static I had the line: HOST_OPT = NO

That causes _DEBUG to be set. When I comment out HOST_OPT=NO in that file then runtests does not generate assert errors on windows-x64-static.

mdavidsaver commented 6 years ago

I've committed 207efca15cf471bbc2990cbd336000e04dcfcd22 as a workaround. @MarkRivers can you see if this gets rid of all the assertion failures?

MarkRivers commented 6 years ago

Before downloading your change I ran the tests on VS2010, VS2015, and VS2017. All were set to HOST_OPT=NO, so the _DEBUG flag would be set which enables the assert.

VS2010 failed with the assert errors I reported previously. VS2015 and VS2017 did not have the assert failures.

I then downloaded your fix and tested again on VS2010. The assert problem is gone. :+1:

It should be OK to only have your fix apply to VS versions prior to VS2015.

mdavidsaver commented 6 years ago

0b6b01ef83fa7100c2ebfdb82e8d5a2c14081a09 changes the condition to

#if defined(_MSC_VER) && _MSC_VER<=1600
mdavidsaver commented 5 years ago

Released with Base 7.0.2