Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > std::move and vc10: bug or misunderstanding?

Reply
Thread Tools

std::move and vc10: bug or misunderstanding?

 
 
Balog Pal
Guest
Posts: n/a
 
      05-25-2013
On 5/24/2013 10:12 PM, Gert-Jan de Vos wrote:
> I ran your test with MSVC10 SP1, 32 bit, boost-1.51.0, Debug: no leaks. If
> I add this leak: "new int;" I see just this single 4 byte leak reported.
>
> Did you install Service Pack 1?


I cut it into my app and produced the same leaks, see my other post
confirming the bug.

 
Reply With Quote
 
 
 
 
Öö Tiib
Guest
Posts: n/a
 
      05-25-2013
On Saturday, 25 May 2013 14:09:02 UTC+3, pasa wrote:
> Good addition to my list of why we should avoid this crapbag called
> std::string.


Good addition to my list of why we should avoid this crapbag called
VS2010. It is broken in too many ways to count. Either use VS2008 (that
is the repaired version of VS2002) or VS2012 that at least contains
some C++11 support.
 
Reply With Quote
 
 
 
 
pasa
Guest
Posts: n/a
 
      05-26-2013
On May 25, 1:09*pm, pasa <(E-Mail Removed)> wrote:
> I'm lazy to look further, my best guess is that a previous move-from
> breaks the internal state, setting the "capacity" to zero instead of
> 16, that triggers this Grow.


Exactly as predicted:

_Myt& assign(_Myt&& _Right)
{ // assign by moving _Right
if (this == &_Right)
;
else if (get_allocator() != _Right.get_allocator()
&& this->_BUF_SIZE <= _Right._Myres)
*this = _Right;
else
{ // not same, clear this and steal from _Right
_Tidy(true);
if (_Right._Myres < this->_BUF_SIZE)
_Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
_Right._Mysize + 1);
else
{ // copy pointer
this->_Bx._Ptr = _Right._Bx._Ptr;
_Right._Bx._Ptr = 0;
}
this->_Mysize = _Right._Mysize;
this->_Myres = _Right._Myres;

_Right._Mysize = 0;
_Right._Myres = 0;
}
return (*this);
}

Note the last
_Right._Myres = 0;
that should happen only under the last condition, for the short case
_Right should better be left alone. With size changing I suspect it
may even have 0-termination at inconsistent place.
 
Reply With Quote
 
Gert-Jan de Vos
Guest
Posts: n/a
 
      05-26-2013
On Sunday, May 26, 2013 1:37:37 PM UTC+2, pasa wrote:
> On May 25, 1:09*pm, pasa <(E-Mail Removed)> wrote:
> > I'm lazy to look further, my best guess is that a previous move-from
> > breaks the internal state, setting the "capacity" to zero instead of
> > 16, that triggers this Grow.

>
> Exactly as predicted:
>
> _Myt& assign(_Myt&& _Right)
> { // assign by moving _Right
> if (this == &_Right)
> ;
> else if (get_allocator() != _Right.get_allocator()
> && this->_BUF_SIZE <= _Right._Myres)
> *this = _Right;
> else
> { // not same, clear this and steal from _Right
> _Tidy(true);
> if (_Right._Myres < this->_BUF_SIZE)
> _Traits::move(this->_Bx._Buf, _Right._Bx._Buf,
> _Right._Mysize + 1);
> else
> { // copy pointer
> this->_Bx._Ptr = _Right._Bx._Ptr;
> _Right._Bx._Ptr = 0;
> }
> this->_Mysize = _Right._Mysize;
> this->_Myres = _Right._Myres;
>
> _Right._Mysize = 0;
> _Right._Myres = 0;
> }
> return (*this);
> }
>
> Note the last
> _Right._Myres = 0;
> that should happen only under the last condition, for the short case
> _Right should better be left alone. With size changing I suspect it
> may even have 0-termination at inconsistent place.


My version of xstring (18/01/2011) has in assign(_Myt&&) instead of:

_Right._Mysize = 0;
_Right._Myres = 0;

This line:

_Right._Tidy();

Tidy sets _Myres to _BUF_SIZE - 1 in this case. This test does not leak
on my system.

These are the version numbers in crtversion.h:

_VC_CRT_MAJOR_VERSION 10
_VC_CRT_MINOR_VERSION 0
_VC_CRT_BUILD_VERSION 40219
_VC_CRT_RBUILD_VERSION 325

Gert-Jan
 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      05-27-2013
On 5/26/2013 4:07 PM, Paavo Helde wrote:
> Balog Pal <(E-Mail Removed)> wrote in news:knq6eo$937$(E-Mail Removed):
>
>> On 5/24/2013 10:12 PM, Gert-Jan de Vos wrote:
>>> I ran your test with MSVC10 SP1, 32 bit, boost-1.51.0, Debug: no
>>> leaks. If I add this leak: "new int;" I see just this single 4 byte
>>> leak reported.
>>>
>>> Did you install Service Pack 1?

>>
>> I cut it into my app and produced the same leaks, see my other post
>> confirming the bug.

>
> Still no leaks detected with "Microsoft Visual Studio 2010 Version
> 10.0.40219.1 SP1Rel", tried both 32- and 64-bit Debug modes.
>
> Also, the line 1981 in my copy of xstring is in the _Pdif function, not
> _Copy as reported by pasa. Seems like this is some kind of bug in MSVC-s
> string implementation which has been fixed at some point (SP1?).


That's interesting, as I also have SP1 installed, and updates enabled --
I recall to see some VS related updates pop up time to time, and I never
reject or hide such a thing.

I'll check the files on our other machines and see whether only mine is
messed up or all, and why.

 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      05-27-2013
On 5/26/2013 4:55 PM, Paavo Helde wrote:

> CString is not standard


As majority of code we work with.

> not portable,


I did port it to several systems in the past without problems or a
workload worth mentioning -- and majority of code we write is not
intended for porting in the first place. for code written in VS it
applies even more.

> decays automatically into const char* pointer,


What is a great feature that makes the std:: version crappy to use with
real-life environment. Like WIN32, someone using VS is pretty likely to
target. And if you deal with code that originated in C, you can replace
char[] buffers without messing up the client code. With std:: version it
requires much work and result in code infested with all those c_str()
noise.

I understand why the standard body did not want that implicit
conversion, but I honestly do not understand most actual users to speak
against. I work with all kind of implicit converting things for more
than two decades and related accidents are still on the theroetic field.
And I keep asking evidence to the contrary and getting silence or
more theory. Certainly I can construct a broken example but it just
fails to happen in practice, and easy to spot on a review. (Or maybe
accident needs some pretty louse policy on pointer usage in general --
for that case I'd guess the implicit conversion will not be a
considerable problem compared to that

> cannot really hold utf-8, etc.


Err, what? Please explain this one.

> What's so sensible about it?


It doesn't have hundreds of unneeded member functions, while lacking the
few that are actually needed and used. Like:

- Format !!!
- the trim family
- make upper and lowercase
- buffer interface with Getbuffer/releasebuffer, so I can set the
content from file, resource, WIN32 API call without using a vector<char>
and then construct a string in the next step

Also it is does COW fine in the MT environment as the interface got not
overlooked. It's convenient in general and is a life-saver for some
special cases with massive sharing.

CString was created by actual engineering, thinking use cases for a
string class, not some monster to demonstrate that you can use it with
generic algorithms in theory.

For the opposite question, why could in make sense to use std::string I
have a single bullet, "it is standard". What makes it a widespread
liability.

 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-27-2013
On Monday, 27 May 2013 09:47:44 UTC+3, Paavo Helde wrote:
> > And if you deal with code that originated in C, you can replace
> > char[] buffers without messing up the client code.

>
> And relying on UB whenever they happen to be passed to printf() or any
> other varargs function. I understand MS is doing their best to make this
> UB work, but it is still UB and makes the code yet more unportable.


Also, MS static analysis tool prefast goes pretty verbose without
(LPCTSTR) noise in such places.

The same trick (sizeof(char*) == sizeof(std::string)) is used by
some open source std::string implementations as well. Just, mentioning
I'm not advocating such extensions nor their usage.

> And if I am using _UNICODE like all Windows code should do nowadays,
> such kind of usage compiles fine and silently misbehaves at run-time.


Really? With _UNICODE that CString is wchar-t*. By docs it looks
like one should use '%ls' format specifiers with 'wchar-t*' arguments.
Not sure about MS C RTL however ... isn't MS C still C89?
 
Reply With Quote
 
pasa
Guest
Posts: n/a
 
      05-27-2013
On May 27, 3:06*am, Balog Pal <(E-Mail Removed)> wrote:
>
> > Also, the line 1981 in my copy of xstring is in the _Pdif function, not
> > _Copy as reported by pasa. Seems like this is some kind of bug in MSVC-s
> > string implementation which has been fixed at some point (SP1?).

>
> That's interesting, as I also have SP1 installed, and updates enabled --
> I recall to see some VS related updates pop up time to time, and I never
> reject or hide such a thing.
>
> I'll check the files on our other machines and see whether only mine is
> messed up or all, and why.


Other machines appear to have the '11 version of xstring. While they
list the same service packs applied in the about box.
I'm re-applying the SP1 to see what happens...

I have a vague recollection to use 'Repair' on the install once in the
past, possibly it created a state that has older files, but keeps the
installed update entries intact? Not very fun.
 
Reply With Quote
 
pasa
Guest
Posts: n/a
 
      05-27-2013
On May 27, 12:20*pm, pasa <(E-Mail Removed)> wrote:
> > That's interesting, as I also have SP1 installed, and updates enabled --
> > I recall to see some VS related updates pop up time to time, and I never
> > reject or hide such a thing.

>
> > I'll check the files on our other machines and see whether only mine is
> > messed up or all, and why.

>
> Other machines appear to have the '11 version of xstring. While they
> list the same service packs applied in the about box.
> I'm re-applying the SP1 to see what happens...
>
> I have a vague recollection to use 'Repair' on the install once in the
> past, possibly it created a state that has older files, but keeps the
> installed update entries intact? *Not very fun.


Using 'Reapply' of the SP1 did not change a thing after using up
insane amount of time.
I had to remove the SP. (The remove action produced a couple of '11
files that belong to some hotfix.)

Then install it again and the fixes from win update -- not really the
fixed files are there and the memory leak disappeared.

Sorry for this last OT, but some other users may get hit be the same
problem, the repair functionality of the installers are FUBAR.

 
Reply With Quote
 
Balog Pal
Guest
Posts: n/a
 
      05-27-2013
On 5/27/2013 8:47 AM, Paavo Helde wrote:
> Balog Pal <(E-Mail Removed)> wrote in news:knudba$2hcm$(E-Mail Removed):
>
>>> CString is not standard

>>
>> As majority of code we work with.
>>
>>> not portable,

>>
>> I did port it to several systems in the past without problems or a
>> workload worth mentioning -- and majority of code we write is not
>> intended for porting in the first place. for code written in VS it
>> applies even more.

>
> You mean, copying (parts of) MFC over to another platform and hacking it
> to work there? Is this even legal?


Something like that. Not sure on the legal fine print, probably it's in
the gray area as I sell the end product didn't see restrictions on where
I compile my source. Even if i couldn't use the original code it is no
problem to re-implement the interface that is pretty lean. But who
cares when YAGNI applies to this case.

>>> decays automatically into const char* pointer,

>>
>> What is a great feature that makes the std:: version crappy to use with
>> real-life environment. Like WIN32, someone using VS is pretty likely to
>> target. And if you deal with code that originated in C, you can

> replace
>> char[] buffers without messing up the client code.

>
> And relying on UB whenever they happen to be passed to printf() or any
> other varargs function.


It is not UB, as the implementation defines the behavior for the case.
You can find it somewhere on msdn.

> I understand MS is doing their best to make this
> UB work, but it is still UB and makes the code yet more unportable.


Undefined by the standard, defined by implementation -- sum is well
defined, and working fine. Certainly on the a different implementation
things could change. Until the theoretic **** hits you're way ahead as
the alternative does not work on any platform to start with.

> And
> if I am using _UNICODE like all Windows code should do nowadays, such
> kind of usage compiles fine and silently misbehaves at run-time.


Dunno, I don't use _UNICODE. But for that realm you shall use all kind
of 'T' stuff consistently and if you do everything works fine.

Also IMO the printf typesafety issue is quite last-century, we have a
ton of static analyzers and this check is the most basic one. and those
who refuse to use static anal have way bigger trouble to start with --
just look the pages of companies creating those tools, most run their
program against open codebases and show example problems and counts.


>> With std:: version it
>> requires much work and result in code infested with all those c_str()
>> noise.

>
> This means you have done the conversion only halfways. And I dislike more
> the (LPCTSTR) noise advocated by MS.


I lost you here.

>>> cannot really hold utf-8, etc.

>>
>> Err, what? Please explain this one.

>
> Just because in an Unicode-aware Windows program CString would be UTF-16.


You're welcome to use CStringA and CStringW instead if config-dependent
changes bother you. But if one wants to have common code that can be
compiled for either 8 or 16 bit chars the MS way works fine even if with
some noise.

In a real setup I'd push for a global decision on one type of config and
just not support the other and enjoy noiseless coding.

> OK, I gather one could use some specialization of CStringT instead, but I
> have never bothered to do this.


?

>>> What's so sensible about it?

>>
>> It doesn't have hundreds of unneeded member functions,

>
> In my mind, it is easier to ignore part of std::string interface than
> ignore the whole of it and learn something else instead.


So you ignore all the 100+ functions and are left with just three usable
ones: regular ctor, range ctor and op+. Is that really worth a standard
class? bah.

> And besides,
> according the MSDN documentation CStringT has more member functions (35)
> than basic_string (32). Maybe you indeed get hundreds if you count
> overloads, but overloads are all doing basically the same jobs so
> learning or ignoring them is easier.


IMO overloads are still members, but we can drop it and switch to count
useful things only.

> Plus std::string does have some member functions which I use all the time
> and which are lacking in CString:
>
> - find_first_not_of, find_last_not_of
> - compare with offset and length arguments
> - append with offset and length arguments


The last one sounds like Mid(), the others I never needed.

>> while lacking the
>> few that are actually needed and used. Like:
>>
>> - Format !!!
>> - the trim family
>> - make upper and lowercase

>
> While these are handy functions sometimes, they have the common problem
> that they are locale-dependent and thus the results are basically
> unpredictable (and there are no variants taking explicit locale
> arguments).


That is true, but poor excuse to discard the most common use.

In my work the locale-specific strings are almost a different family,
while I have heavy use that is tied to ASCII set. "Key"s in the program
used in all kind of technical files and such.

The really localized things are firewalled away from the rest of the
program.

> Even the wide version CString MakeUpper() seems to depend on
> the narrow codepage locale (by reasons beyond my comprehension) and
> produces some crap instead of working properly.


Probably so, but it's a different story for a different day. Messing the
core use cases of the string is a source of problems. One violent case
to recall: we had problems with xml and especially xslt conversions on
linux. it took hours literally. We profiled the problem to operator ==
of Glib::ustring. Which we replaced (in experimental setup) with simple
strcmp, to gain some 100x speed with the same behavior. It was
normalizing the content before doing actual compare -- as unicode is
messed up with precomposed characters and other such stuff. Certainly
nothing like was needed with our data that had ascii keys only, and even
if we wanted arbitrary things it would be presented in a consistent,
prenormalized way. So simple strcmp would serve.

IMNSHO imperfect generic locale support should never prevent
implementation of the most frequent uses of strings.

>> - buffer interface with Getbuffer/releasebuffer, so I can set the
>> content from file, resource, WIN32 API call without using a vector

> <char>
>> and then construct a string in the next step
>>
>> Also it is does COW fine in the MT environment as the interface got not
>> overlooked. It's convenient in general and is a life-saver for some
>> special cases with massive sharing.

>
> I think this is a single point for CString so far.


And a really big one really -- especially as I mentioned that in real
life you will have many extensions, where string will be a basic LEGO
piece. The C++98 version of std::string is just hostile for them with
its forced copy and lack of linear storage. While CString has all the
pieces out of the box.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
*bug* *bug* *bug* David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM
ASP.NET Login control bug or SQL 2005 bug? RedEye ASP .Net 2 12-13-2005 10:57 AM
Re: BUG? OR NOT A BUG? John ASP .Net 2 09-21-2005 10:31 AM
rdoc bug (and rdoc bug tracker site is down) Brian Schröder Ruby 5 09-18-2004 02:08 PM
how to report bug to g++ ? got a bug and fixed up source code DarkSpy C++ 4 06-27-2003 09:05 AM



Advertisments