#7 Compilation error with MSVC6 on ::operator delete[]

current_series
closed-fixed
5
2007-03-05
2007-03-04
Vincent Rivière
No

Compilation failure
using Visual C++ 6.0 SP6
and Smieciuch 0.6.3-rc3

Compiling...
gcpptest.cpp
F:\Lib\smieciuch-0.6.4-rc3\include\gc.hpp(133) : error C2039: 'delete[]' : is not a member of '`global namespace''
F:\Lib\smieciuch-0.6.4-rc3\include\gc.hpp(127) : while compiling class-template member function 'void __cdecl gc::detail::destructor<class gc::gc_ptr<int> >::destroy_array(void *,void *,unsigned int)'
F:\Lib\smieciuch-0.6.4-rc3\include\gc.hpp(133) : error C2065: 'delete[]' : undeclared identifier
F:\Lib\smieciuch-0.6.4-rc3\include\gc.hpp(127) : while compiling class-template member function 'void __cdecl gc::detail::destructor<class gc::gc_ptr<int> >::destroy_array(void *,void *,unsigned int)'

The reason is that VC6 does not have a global operator delete[](). When deleting an array with delete[], it calls all the destructors, then the global operator delete(). However, a class can override its operator delete[](), which will be called as expected.

The same things apply to operator new[]().

A quick and dirty fix may be :

#if _MSC_VER <= 1200
::operator delete(base);
#else
::operator delete[](base);
#endif

However, I can't unserstand why you changed the implementation of struct destructor. The old version called delete and delete[]. Now you do the same thing, but by hand.

Discussion

  • Logged In: YES
    user_id=1260797
    Originator: YES

    When bug #1673456 is fixed, a better fix may be :

    #ifdef _SMGC_NO_ARRAY_NEW
    ::operator delete(base);
    #else
    ::operator delete[](base);
    #endif

     
    • assigned_to: nobody --> sebaska
    • status: open --> closed-fixed
     
  • Logged In: YES
    user_id=759310
    Originator: NO

    Well it has been done that way because it should be done that way, as operator new(GC) calls ::operator new(size) not new T(...). Mixing ::operator new() with delete T is not C++ standard compliant, AFAIR.

    So the fix will be:

    #if _MSC_VER <= 1200
    ::operator delete(base);
    #else
    ::operator delete[](base);
    #endif