[Digikam-devel] Re: delete does not reset the pointer in GCC (4.6.0)
Francesco R.
francesco at pnpitalia.it
Wed Jun 15 13:32:47 BST 2011
On Wednesday 15 June 2011 11:55:50 Marcel Wiesweg wrote:
> > a few months ago, maybe 2 years.
> > I know that I always added
> > xyz = 0;
> > to my code before, but then it was removed again because it is not
> > neccessary with modern compilers (I don't know who said that).
>
> When googling and reading through the usual sources (stackoverflow etc.) I
> see noone saying that any compiler sets a pointer to 0, I would even guess
> delete should _not_ change the value of the passed pointer unless the C++
> standard says so. There are the usual stories not to use raw pointers and
> use concepts to make sure you are always sure never to use deleted pointers
> again, but in the end, if you are playing with raw pointers (which we are
> doing still in too many areas IMO, but getting less) and need to delete and
> reuse the variable, be sure to set it to 0.
>
> Marcel
Disclaimer I do know nothing of c++ remember? please do take it in account.
This excided my curiosity too, and I've booth gcc-4.5 and 4.6 installed so
tested the program below.
As far as I can see gcc does nothing to put a 0 in the pointer, neither in 4.5
version, it does add a check before the "delete" call to avoid deleting a 0
pointer but nothing else.
you can search for label "startLookingAtMe" in the gimple code attached
(gimple is a low level rappresentation of the code used by gcc internally)
#include <iostream>
/*
g++-4.5.2 -O0 -ggdb3 -fdump-tree-gimple a.cpp \
&& mv a.cpp.004t.gimple a.cpp.004t.gcc45.gimple
g++-4.6.0 -O0 -ggdb3 -fdump-tree-gimple a.cpp \
&& mv a.cpp.004t.gimple a.cpp.004t.gcc46.gimple
# to compare use:
sed -i -e 's:[0-9][0-9][0-9][0-9][0-9]:99999:g' a.*.gimple
NO CHANGES g++-4.6.0 -O0 -fno-delete-null-pointer-checks -ggdb3 -fdump-tree-
gimple a.cpp && mv a.cpp.004t.gimple a.cpp.004t.gcc46dncp.gimple
*/
using namespace std;
main()
{
int * p;
p= new (nothrow) int[2];
p[0] = 1; p[1] = 2;
for (int n=0; n<2; n++)
cout << p[n] << ", ";
cout << endl;
startLookingAtMe:
delete[] p;
p = 0; // omitting this crashes
delete[] p;
if (p) delete p;
endLookingAtMe:
cout << (0/0); // my easy brakpoint
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: a.cpp
Type: text/x-c++src
Size: 738 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/digikam-devel/attachments/20110615/e5ff7ccb/attachment.cpp>
-------------- next part --------------
(static initializers for a.cpp) ()
{
__static_initialization_and_destruction_0 (1, 65535);
}
void __static_initialization_and_destruction_0(int, int) (int __initialize_p, int __priority)
{
void (*<Tbc>) (void *) __comp_dtor .0;
if (__initialize_p == 1) goto <D.21277>; else goto <D.21278>;
<D.21277>:
if (__priority == 65535) goto <D.21279>; else goto <D.21280>;
<D.21279>:
std::ios_base::Init::Init (&__ioinit);
__comp_dtor .0 = (void (*<Tbc>) (void *)) __comp_dtor ;
__cxa_atexit (__comp_dtor .0, &__ioinit, &__dso_handle);
goto <D.21282>;
<D.21280>:
<D.21282>:
goto <D.21283>;
<D.21278>:
<D.21283>:
}
int main() ()
{
void * D.21284;
int * D.21285;
bool D.21289;
long unsigned int D.21291;
long unsigned int D.21292;
int * D.21293;
int D.21294;
struct basic_ostream & D.21295;
int D.21305;
int D.21306;
{
int * p;
D.21284 = operator new [] (8, ¬hrow);
p = (int *) D.21284;
*p = 1;
D.21285 = p + 4;
*D.21285 = 2;
{
int n;
n = 0;
goto <D.21290>;
<D.21288>:
D.21291 = (long unsigned int) n;
D.21292 = D.21291 * 4;
D.21293 = p + D.21292;
D.21294 = *D.21293;
D.21295 = std::basic_ostream<char>::operator<< (&cout, D.21294);
std::operator<< <std::char_traits<char> > (D.21295, &", "[0]);
n = n + 1;
<D.21290>:
D.21289 = n <= 1;
if (D.21289 != 0) goto <D.21288>; else goto <D.21286>;
<D.21286>:
}
std::basic_ostream<char>::operator<< (&cout, endl);
startLookingAtMe:
if (p != 0B) goto <D.21296>; else goto <D.21297>;
<D.21296>:
operator delete [] (p);
goto <D.21298>;
<D.21297>:
<D.21298>:
if (p != 0B) goto <D.21299>; else goto <D.21300>;
<D.21299>:
operator delete [] (p);
goto <D.21301>;
<D.21300>:
<D.21301>:
if (p != 0B) goto <D.21302>; else goto <D.21303>;
<D.21302>:
operator delete (p);
goto <D.21304>;
<D.21303>:
<D.21304>:
endLookingAtMe:
D.21305 = 0 / 0;
std::basic_ostream<char>::operator<< (&cout, D.21305);
}
D.21306 = 0;
return D.21306;
}
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with _Traits = std::char_traits<char>] (struct basic_ostream & __out, const char * __s)
{
struct basic_ios * __out.1;
int (*__vtbl_ptr_type) (void) * D.21312;
int (*__vtbl_ptr_type) (void) * D.21313;
long int * D.21314;
long int D.21315;
long unsigned int D.21316;
struct basic_ios * D.21317;
size_t D.21319;
streamsize D.21320;
struct basic_ostream & D.21321;
if (__s == 0B) goto <D.21309>; else goto <D.21310>;
<D.21309>:
__out.1 = (struct basic_ios *) __out;
D.21312 = __out->_vptr.basic_ostream;
D.21313 = D.21312 + -24;
D.21314 = (long int *) D.21313;
D.21315 = *D.21314;
D.21316 = (long unsigned int) D.21315;
D.21317 = __out.1 + D.21316;
std::basic_ios<char>::setstate (D.21317, 1);
goto <D.21318>;
<D.21310>:
D.21319 = std::char_traits<char>::length (__s);
D.21320 = (streamsize) D.21319;
std::__ostream_insert<char, std::char_traits<char> > (__out, __s, D.21320);
<D.21318>:
D.21321 = __out;
return D.21321;
}
void std::basic_ios<_CharT, _Traits>::setstate(std::ios_base::iostate) [with _CharT = char, _Traits = std::char_traits<char>, std::ios_base::iostate = std::_Ios_Iostate] (struct basic_ios * const this, iostate __state)
{
iostate D.21323;
_Ios_Iostate D.21324;
D.21323 = std::basic_ios<char>::rdstate (this);
D.21324 = std::operator| (D.21323, __state);
std::basic_ios<char>::clear (this, D.21324);
}
std::ios_base::iostate std::basic_ios<_CharT, _Traits>::rdstate() const [with _CharT = char, _Traits = std::char_traits<char>, std::ios_base::iostate = std::_Ios_Iostate] (const struct basic_ios * const this)
{
iostate D.21326;
D.21326 = this->D.18578._M_streambuf_state;
return D.21326;
}
std::_Ios_Iostate std::operator|(std::_Ios_Iostate, std::_Ios_Iostate) (_Ios_Iostate __a, _Ios_Iostate __b)
{
_Ios_Iostate D.21328;
int __a.2;
int __b.3;
int D.21331;
__a.2 = (int) __a;
__b.3 = (int) __b;
D.21331 = __a.2 | __b.3;
D.21328 = (_Ios_Iostate) D.21331;
return D.21328;
}
static size_t std::char_traits<char>::length(const std::char_traits<char>::char_type*) (const char_type * __s)
{
size_t D.21333;
D.21333 = __builtin_strlen (__s);
return D.21333;
}
std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] (struct basic_ostream * const this, struct __ostream_type & (*<T318c>) (struct __ostream_type &) __pf)
{
struct __ostream_type & D.21335;
D.21335 = __pf (this);
return D.21335;
}
std::basic_ostream<_CharT, _Traits>& std::endl(std::basic_ostream<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>] (struct basic_ostream & __os)
{
struct basic_ostream & D.21338;
struct basic_ios * __os.4;
int (*__vtbl_ptr_type) (void) * D.21340;
int (*__vtbl_ptr_type) (void) * D.21341;
long int * D.21342;
long int D.21343;
long unsigned int D.21344;
struct basic_ios * D.21345;
char_type D.21346;
int D.21347;
struct basic_ostream & D.21348;
__os.4 = (struct basic_ios *) __os;
D.21340 = __os->_vptr.basic_ostream;
D.21341 = D.21340 + -24;
D.21342 = (long int *) D.21341;
D.21343 = *D.21342;
D.21344 = (long unsigned int) D.21343;
D.21345 = __os.4 + D.21344;
D.21346 = std::basic_ios<char>::widen (D.21345, 10);
D.21347 = (int) D.21346;
D.21348 = std::basic_ostream<char>::put (__os, D.21347);
D.21338 = std::flush<char, std::char_traits<char> > (D.21348);
return D.21338;
}
char_type std::basic_ios<_CharT, _Traits>::widen(char) const [with _CharT = char, _Traits = std::char_traits<char>, char_type = char] (const struct basic_ios * const this, char __c)
{
char_type D.21353;
int D.21354;
const struct __ctype_type * const D.21355;
const struct ctype & D.21356;
D.21354 = (int) __c;
D.21355 = this->_M_ctype;
D.21356 = std::__check_facet<std::ctype<char> > (D.21355);
D.21353 = std::ctype<char>::widen (D.21356, D.21354);
return D.21353;
}
const _Facet& std::__check_facet(const _Facet*) [with _Facet = std::ctype<char>] (const struct ctype * __f)
{
const struct ctype & D.21362;
if (__f == 0B) goto <D.21360>; else goto <D.21361>;
<D.21360>:
std::__throw_bad_cast ();
<D.21361>:
D.21362 = __f;
return D.21362;
}
std::ctype<char>::char_type std::ctype<char>::widen(char) const (const struct ctype * const this, char __c)
{
char D.21364;
char_type D.21367;
unsigned char __c.5;
int D.21369;
int (*__vtbl_ptr_type) (void) * D.21370;
int (*__vtbl_ptr_type) (void) * D.21371;
int (*__vtbl_ptr_type) (void) D.21372;
int D.21373;
D.21364 = this->_M_widen_ok;
if (D.21364 != 0) goto <D.21365>; else goto <D.21366>;
<D.21365>:
__c.5 = (unsigned char) __c;
D.21369 = (int) __c.5;
D.21367 = this->_M_widen[D.21369];
return D.21367;
<D.21366>:
std::ctype<char>::_M_widen_init (this);
D.21370 = this->D.15545._vptr.facet;
D.21371 = D.21370 + 48;
D.21372 = *D.21371;
D.21373 = (int) __c;
D.21367 = OBJ_TYPE_REF(D.21372;this->6) (this, D.21373);
return D.21367;
}
std::basic_ostream<_CharT, _Traits>& std::flush(std::basic_ostream<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>] (struct basic_ostream & __os)
{
struct basic_ostream & D.21376;
D.21376 = std::basic_ostream<char>::flush (__os);
return D.21376;
}
-------------- next part --------------
(static initializers for a.cpp) ()
{
__static_initialization_and_destruction_0 (1, 65535);
}
void __static_initialization_and_destruction_0(int, int) (int __initialize_p, int __priority)
{
void (*<Tbc>) (void *) __comp_dtor .0;
if (__initialize_p == 1) goto <D.21292>; else goto <D.21293>;
<D.21292>:
if (__priority == 65535) goto <D.21294>; else goto <D.21295>;
<D.21294>:
std::ios_base::Init::Init (&__ioinit);
__comp_dtor .0 = (void (*<Tbc>) (void *)) __comp_dtor ;
__cxa_atexit (__comp_dtor .0, &__ioinit, &__dso_handle);
goto <D.21297>;
<D.21295>:
<D.21297>:
goto <D.21298>;
<D.21293>:
<D.21298>:
}
int main() ()
{
int * D.21299;
bool D.21303;
long unsigned int D.21305;
long unsigned int D.21306;
int * D.21307;
int D.21308;
struct basic_ostream & D.21309;
int D.21319;
int D.21320;
{
int * p;
p = operator new [] (8, ¬hrow);
*p = 1;
D.21299 = p + 4;
*D.21299 = 2;
{
int n;
n = 0;
goto <D.21304>;
<D.21302>:
D.21305 = (long unsigned int) n;
D.21306 = D.21305 * 4;
D.21307 = p + D.21306;
D.21308 = *D.21307;
D.21309 = std::basic_ostream<char>::operator<< (&cout, D.21308);
std::operator<< <std::char_traits<char> > (D.21309, ", ");
n = n + 1;
<D.21304>:
D.21303 = n <= 1;
if (D.21303 != 0) goto <D.21302>; else goto <D.21300>;
<D.21300>:
}
std::basic_ostream<char>::operator<< (&cout, endl);
startLookingAtMe:
if (p != 0B) goto <D.21310>; else goto <D.21311>;
<D.21310>:
operator delete [] (p);
goto <D.21312>;
<D.21311>:
<D.21312>:
p = 0B;
if (p != 0B) goto <D.21313>; else goto <D.21314>;
<D.21313>:
operator delete [] (p);
goto <D.21315>;
<D.21314>:
<D.21315>:
if (p != 0B) goto <D.21316>; else goto <D.21317>;
<D.21316>:
operator delete (p);
goto <D.21318>;
<D.21317>:
<D.21318>:
endLookingAtMe:
D.21319 = 0 / 0;
std::basic_ostream<char>::operator<< (&cout, D.21319);
}
D.21320 = 0;
return D.21320;
}
std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*) [with _Traits = std::char_traits<char>] (struct basic_ostream & __out, const char * __s)
{
int (*__vtbl_ptr_type) (void) * D.21325;
int (*__vtbl_ptr_type) (void) * D.21326;
long int D.21327;
long unsigned int D.21328;
struct basic_ios * D.21329;
size_t D.21331;
streamsize D.21332;
struct basic_ostream & D.21333;
if (__s == 0B) goto <D.21323>; else goto <D.21324>;
<D.21323>:
D.21325 = __out->_vptr.basic_ostream;
D.21326 = D.21325 + -24;
D.21327 = MEM[(long int *)D.21326];
D.21328 = (long unsigned int) D.21327;
D.21329 = __out + D.21328;
std::basic_ios<char>::setstate (D.21329, 1);
goto <D.21330>;
<D.21324>:
D.21331 = std::char_traits<char>::length (__s);
D.21332 = (streamsize) D.21331;
std::__ostream_insert<char, std::char_traits<char> > (__out, __s, D.21332);
<D.21330>:
D.21333 = __out;
return D.21333;
}
void std::basic_ios<_CharT, _Traits>::setstate(std::ios_base::iostate) [with _CharT = char, _Traits = std::char_traits<char>, std::ios_base::iostate = std::_Ios_Iostate] (struct basic_ios * this, iostate __state)
{
iostate D.21335;
_Ios_Iostate D.21336;
D.21335 = std::basic_ios<char>::rdstate (this);
D.21336 = std::operator| (D.21335, __state);
std::basic_ios<char>::clear (this, D.21336);
}
std::ios_base::iostate std::basic_ios<_CharT, _Traits>::rdstate() const [with _CharT = char, _Traits = std::char_traits<char>, std::ios_base::iostate = std::_Ios_Iostate] (const struct basic_ios * this)
{
iostate D.21338;
D.21338 = this->D.18587._M_streambuf_state;
return D.21338;
}
std::_Ios_Iostate std::operator|(std::_Ios_Iostate, std::_Ios_Iostate) (_Ios_Iostate __a, _Ios_Iostate __b)
{
_Ios_Iostate D.21340;
int __a.1;
int __b.2;
int D.21343;
__a.1 = (int) __a;
__b.2 = (int) __b;
D.21343 = __a.1 | __b.2;
D.21340 = (_Ios_Iostate) D.21343;
return D.21340;
}
static std::size_t std::char_traits<char>::length(const char_type*) (const char_type * __s)
{
size_t D.21345;
D.21345 = __builtin_strlen (__s);
return D.21345;
}
std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] (struct basic_ostream * this, struct __ostream_type & (*<T372f>) (struct __ostream_type &) __pf)
{
struct __ostream_type & D.21347;
D.21347 = __pf (this);
return D.21347;
}
std::basic_ostream<_CharT, _Traits>& std::endl(std::basic_ostream<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>] (struct basic_ostream & __os)
{
struct basic_ostream & D.21350;
int (*__vtbl_ptr_type) (void) * D.21351;
int (*__vtbl_ptr_type) (void) * D.21352;
long int D.21353;
long unsigned int D.21354;
struct basic_ios * D.21355;
char_type D.21356;
int D.21357;
struct basic_ostream & D.21358;
D.21351 = __os->_vptr.basic_ostream;
D.21352 = D.21351 + -24;
D.21353 = MEM[(long int *)D.21352];
D.21354 = (long unsigned int) D.21353;
D.21355 = __os + D.21354;
D.21356 = std::basic_ios<char>::widen (D.21355, 10);
D.21357 = (int) D.21356;
D.21358 = std::basic_ostream<char>::put (__os, D.21357);
D.21350 = std::flush<char, std::char_traits<char> > (D.21358);
return D.21350;
}
std::basic_ios<_CharT, _Traits>::char_type std::basic_ios<_CharT, _Traits>::widen(char) const [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ios<_CharT, _Traits>::char_type = char] (const struct basic_ios * this, char __c)
{
char_type D.21363;
int D.21364;
const struct __ctype_type * const D.21365;
const struct ctype & D.21366;
D.21364 = (int) __c;
D.21365 = this->_M_ctype;
D.21366 = std::__check_facet<std::ctype<char> > (D.21365);
D.21363 = std::ctype<char>::widen (D.21366, D.21364);
return D.21363;
}
const _Facet& std::__check_facet(const _Facet*) [with _Facet = std::ctype<char>] (const struct ctype * __f)
{
const struct ctype & D.21372;
if (__f == 0B) goto <D.21370>; else goto <D.21371>;
<D.21370>:
std::__throw_bad_cast ();
<D.21371>:
D.21372 = __f;
return D.21372;
}
std::ctype<char>::char_type std::ctype<char>::widen(char) const (const struct ctype * const this, char __c)
{
char D.21374;
char_type D.21377;
unsigned char __c.3;
int D.21379;
int (*__vtbl_ptr_type) (void) * D.21380;
int (*__vtbl_ptr_type) (void) * D.21381;
int (*__vtbl_ptr_type) (void) D.21382;
int D.21383;
D.21374 = this->_M_widen_ok;
if (D.21374 != 0) goto <D.21375>; else goto <D.21376>;
<D.21375>:
__c.3 = (unsigned char) __c;
D.21379 = (int) __c.3;
D.21377 = this->_M_widen[D.21379];
return D.21377;
<D.21376>:
std::ctype<char>::_M_widen_init (this);
D.21380 = this->D.15550._vptr.facet;
D.21381 = D.21380 + 48;
D.21382 = *D.21381;
D.21383 = (int) __c;
D.21377 = OBJ_TYPE_REF(D.21382;this->6) (this, D.21383);
return D.21377;
}
std::basic_ostream<_CharT, _Traits>& std::flush(std::basic_ostream<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>] (struct basic_ostream & __os)
{
struct basic_ostream & D.21386;
D.21386 = std::basic_ostream<char>::flush (__os);
return D.21386;
}
virtual const char_type* std::ctype<char>::do_narrow(const char_type*, const char_type*, char, char*) const (const struct ctype * const this, const char_type * __lo, const char_type * __hi, char D.15511, char * __dest)
{
long int __hi.4;
long int __lo.5;
long int D.21391;
long unsigned int D.21392;
const char_type * D.21393;
__hi.4 = (long int) __hi;
__lo.5 = (long int) __lo;
D.21391 = __hi.4 - __lo.5;
D.21392 = (long unsigned int) D.21391;
__builtin_memcpy (__dest, __lo, D.21392);
D.21393 = __hi;
return D.21393;
}
virtual char std::ctype<char>::do_narrow(std::ctype<char>::char_type, char) const (const struct ctype * const this, char_type __c, char D.15506)
{
char D.21395;
D.21395 = __c;
return D.21395;
}
virtual const char* std::ctype<char>::do_widen(const char*, const char*, std::ctype<char>::char_type*) const (const struct ctype * const this, const char * __lo, const char * __hi, char_type * __dest)
{
long int __hi.6;
long int __lo.7;
long int D.21399;
long unsigned int D.21400;
const char * D.21401;
__hi.6 = (long int) __hi;
__lo.7 = (long int) __lo;
D.21399 = __hi.6 - __lo.7;
D.21400 = (long unsigned int) D.21399;
__builtin_memcpy (__dest, __lo, D.21400);
D.21401 = __hi;
return D.21401;
}
virtual std::ctype<char>::char_type std::ctype<char>::do_widen(char) const (const struct ctype * const this, char __c)
{
char_type D.21403;
D.21403 = __c;
return D.21403;
}
More information about the Digikam-devel
mailing list