Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Unexpected compiler behavior relating to size_t and boost - VisualStudio 2005.

Reply
Thread Tools

Unexpected compiler behavior relating to size_t and boost - VisualStudio 2005.

 
 
Unknownmat
Guest
Posts: n/a
 
      07-13-2008
Hello,

I am using Visual Studio 2005 (msvc 8.0, I believe). I am experience
some unexpected compiler warnings that have to do with how integer
types, size_t, and boost interact. I hope that somebody on this list
might know what's going on.

Here is the smallest code I could come up with to reproduce the
behavior:

#include <vector>
#include <functional>
#include <boost/function.hpp>

template< class T >
void test()
{
typedef std::vector< T > TItems;
typedef boost::function< bool (T, T) > TCompFn;
typedef std::vector< std::size_t > TSizes;

TItems data;
TCompFn fn = TCompFn( std::greater< T >() );
fn( data.front(), data.front() ); // NOTE: data is empty - will
cause a runtime error if run
}

int main()
{
test< int >();
test< unsigned >();
}


When I compile this, I get the following warning about the line
"fn( data.front(), data.front() );":
warning C4267: 'argument' : conversion from 'size_t' to 'unsigned
int', possible loss of data

This warning will go away when I do any of the following:
- Comment out EITHER line in the main function.
- Use a 'naked' std::greater< T >, rather than a boost::function<
bool (T, T) >
- comment out the typedef std::vector< std::size_t > TSizes;

I thought that size_t was distinct form the various integer types -
and the compiler warning seems to confirm this - but based on the fact
that commenting out the vector< size_t> typedef removes the warning,
this typedef seems to be stepping on my earlier vector< T > typedef.

Based on the fact that using greater< T > instead of function< bool
(T,T) > fixes the problem -- I wonder if some boost size_t definition
somehow steps on std::size_t?

And finally, I'm completely stumped why commenting out either line in
main() 'fixes' the problem.

Anyway, thanks for your time, any help would be appreciated.

Matt
 
Reply With Quote
 
 
 
 
Unknownmat
Guest
Posts: n/a
 
      07-13-2008
> Here is the smallest code I could come up with to reproduce the
> behavior:
>
> #include <vector>
> #include <functional>
> #include <boost/function.hpp>
>
> template< class T >
> void test()
> {
> typedef std::vector< T > TItems;
> typedef boost::function< bool (T, T) > TCompFn;
> typedef std::vector< std::size_t > TSizes;
>
> TItems data;
> TCompFn fn = TCompFn( std::greater< T >() );
> fn( data.front(), data.front() ); // NOTE: data is empty - will
> cause a runtime error if run
>
> }
>
> int main()
> {
> test< int >();
> test< unsigned >();
>
> }
>


I was able to reproduce the warning with an even smaller snippet of
code:

#include <vector>
#include <functional>
#include <boost/function.hpp>

int main()
{
std::vector< std::size_t > sizes;
std::vector< unsigned > data;

boost::function< bool (unsigned, unsigned) > fn = std::greater<
unsigned >();
fn( data.front(), 10 );
}

The warning goes away if I comment out the line "std::vector<
std::size_t > sizes;". This behavior baffles me. Any insight would
again be appreciated.

Thanks,
Matt
 
Reply With Quote
 
 
 
 
Christian Hackl
Guest
Posts: n/a
 
      07-14-2008
Unknownmat wrote:

> I was able to reproduce the warning with an even smaller snippet of
> code:
>
> #include <vector>
> #include <functional>
> #include <boost/function.hpp>
>
> int main()
> {
> std::vector< std::size_t > sizes;
> std::vector< unsigned > data;
>
> boost::function< bool (unsigned, unsigned) > fn = std::greater<
> unsigned >();
> fn( data.front(), 10 );
> }
>
> The warning goes away if I comment out the line "std::vector<
> std::size_t > sizes;". This behavior baffles me. Any insight would
> again be appreciated.


I cannot reproduce C4267 myself with MSVC 8.0 and Boost 1.35.0, not even
with /Wall. I suggest you try microsoft.public.vc.language (which is the
proper place to ask VC-specific questions, anyway).


--
Christian Hackl
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      07-14-2008
Unknownmat wrote:
> I am using Visual Studio 2005 (msvc 8.0, I believe). I am experience
> some unexpected compiler warnings that have to do with how integer
> types, size_t, and boost interact.


VS2005 has a bug related to this. When you use size_t, it internally
converts it to 'unsigned int'. In some situations it forgets that the
type was actually size_t and only sees it's an 'unsigned int', so when
you eg. assign a size_t value to such a "unsigned int which was a size_t
but VS2005 has forgotten about it", it will give you a warning about
possible data loss (because it only sees that a size_t is being assigned
to an unsigned int, and this triggers its warning about possible loss of
data, as size_t may be bigger than unsigned int in another system).

I don't know if anything can be done about that, except turning the
warning off. (You can turn it off on a per-file basis using a #pragma.)
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-14-2008
On Jul 14, 4:51 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> Unknownmat wrote:
> > I am using Visual Studio 2005 (msvc 8.0, I believe). I am experience
> > some unexpected compiler warnings that have to do with how integer
> > types, size_t, and boost interact.


> VS2005 has a bug related to this. When you use size_t, it internally
> converts it to 'unsigned int'. In some situations it forgets that the
> type was actually size_t and only sees it's an 'unsigned int',


How is that a bug? size_t is required to be a typedef, not a
real type, and on a lot of 32 bit machines, it is an unsigned
int. Not "gets converted to", but "is".

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Unknownmat
Guest
Posts: n/a
 
      07-14-2008
Thanks for the response - it wasn't clear to me that this was a MSVC
specific bug. Perhaps I shouldn't have added that to the title,
except that I knew it would come up (and rightfully so, apparently).

Curiously, are you using VS 2005 with SP1? I've been able to
reproduce this fairly consistently on multiple computers. I'm a bit
surprised that you say that you cannot reproduce it.

Thanks,
Matt

Christian Hackl wrote:
> Unknownmat wrote:
>
> > I was able to reproduce the warning with an even smaller snippet of
> > code:
> >
> > #include <vector>
> > #include <functional>
> > #include <boost/function.hpp>
> >
> > int main()
> > {
> > std::vector< std::size_t > sizes;
> > std::vector< unsigned > data;
> >
> > boost::function< bool (unsigned, unsigned) > fn = std::greater<
> > unsigned >();
> > fn( data.front(), 10 );
> > }
> >
> > The warning goes away if I comment out the line "std::vector<
> > std::size_t > sizes;". This behavior baffles me. Any insight would
> > again be appreciated.

>
> I cannot reproduce C4267 myself with MSVC 8.0 and Boost 1.35.0, not even
> with /Wall. I suggest you try microsoft.public.vc.language (which is the
> proper place to ask VC-specific questions, anyway).
>
>
> --
> Christian Hackl

 
Reply With Quote
 
Unknownmat
Guest
Posts: n/a
 
      07-14-2008
Juha Nieminen wrote:
> Unknownmat wrote:
> > I am using Visual Studio 2005 (msvc 8.0, I believe). I am experience
> > some unexpected compiler warnings that have to do with how integer
> > types, size_t, and boost interact.

>
> VS2005 has a bug related to this. When you use size_t, it internally
> converts it to 'unsigned int'. In some situations it forgets that the
> type was actually size_t and only sees it's an 'unsigned int', so when
> you eg. assign a size_t value to such a "unsigned int which was a size_t
> but VS2005 has forgotten about it", it will give you a warning about
> possible data loss (because it only sees that a size_t is being assigned
> to an unsigned int, and this triggers its warning about possible loss of
> data, as size_t may be bigger than unsigned int in another system).
>
> I don't know if anything can be done about that, except turning the
> warning off. (You can turn it off on a per-file basis using a #pragma.)


Thanks for the response that helps immensley. Do you happen to have a
Microsoft KB link?

I will do some more digging now that I know that this is VS2005
related. What's interesting to me is that I am very careful about
using size_t - I never need to typecast between unsigned and size_t
(unless I'm forced to by a library API or something). In the example
I posted above, in fact, I'm not even USING the vector< size_t> object
- there's simply no way this object could cause a conversion error.

Thanks,
Matt
 
Reply With Quote
 
Unknownmat
Guest
Posts: n/a
 
      07-14-2008
On Jul 13, 3:42*pm, Unknownmat <(E-Mail Removed)> wrote:
> The warning goes away if I comment out the line "std::vector<
> std::size_t > sizes;". *This behavior baffles me. *Any insight would
> again be appreciated.
>
> Thanks,
> Matt- Hide quoted text -
>
> - Show quoted text -


In case anybody is interested - I figured out what's causing this
issue. Microsoft's "detect 64-bit portability issues" compiler option
causes both false-positives, and false-negatives, and interacts poorly
with templates. This is clearly one of those cases.

Turning off the "/Wp64" switch will eliminate this false warning.

Thanks for the help. Sorry for being OT.

Matt
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      07-14-2008
Unknownmat wrote:
> What's interesting to me is that I am very careful about
> using size_t - I never need to typecast between unsigned and size_t
> (unless I'm forced to by a library API or something). In the example
> I posted above, in fact, I'm not even USING the vector< size_t> object
> - there's simply no way this object could cause a conversion error.


That's the funny side-effect of that bug: Even if there isn't even a
single "int" or "unsigned int" in the entire program, only size_t (and
some template, which is what usually causes the problem), the compiler
will still trigger a warning about an inexistent "unsigned int".

(The problem is understandable because when compiling a 32-bit program
size_t *is* an unsigned int, but other compilers are able to retain the
info that it was, actually, a size_t all the way and they don't give any
warnings.)
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-15-2008
On Jul 14, 7:42 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> Unknownmat wrote:
> > What's interesting to me is that I am very careful about
> > using size_t - I never need to typecast between unsigned and size_t
> > (unless I'm forced to by a library API or something). In the example
> > I posted above, in fact, I'm not even USING the vector< size_t> object
> > - there's simply no way this object could cause a conversion error.


> That's the funny side-effect of that bug: Even if there isn't
> even a single "int" or "unsigned int" in the entire program,
> only size_t (and some template, which is what usually causes
> the problem), the compiler will still trigger a warning about
> an inexistent "unsigned int".


> (The problem is understandable because when compiling a 32-bit
> program size_t *is* an unsigned int, but other compilers are
> able to retain the info that it was, actually, a size_t all
> the way and they don't give any warnings.)


I think you have it backwards. Other compilers simply consider
it an unsigned int (or whatever), and get on with it; they don't
try to treat size_t differently from whatever it is typedef'ed
to.

Which is, of course, what the standard says the compiler should
do.

Of course, there's nothing wrong with keeping the fact that this
unsigned int was originally a size_t, for things like error
messages, e.g. displaying std::vector< size_t ... > instead of
std::vector< unsigned int ... >. But in practice, most don't
seem to: if I write:
std::vector< std::size_t > v ;
v.push_back( 1, 2 ) ;
both g++ and Sun CC complain about an error using a member
function of "std::vector<unsigned int, std::allocator<unsigned
int> >" (g++) or "std::vector<unsigned>" (Sun CC). Only VC++
retains this information, displaying an error in
"std::vector<_Ty>", but later indicating that _Ty=size_t (which
is actually pretty nice---it's nice, too, that both Sun CC and
VC++ omit mentionning the allocator).

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
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
reinterpret_cast<std::size_t>(p) and reinterpret_cast<std::size_t&>() Alex Vinokur C++ 1 02-06-2011 07:48 AM
Need to find the _MSC_VER for my VisualStudio C++ compiler RichardOnRails C++ 4 04-18-2010 04:42 PM
Casting from const pair<const unsigned char*, size_t>* to constpair<unsigned char*, size_t>* Alex Vinokur C++ 9 10-13-2008 05:05 PM
Boost::any and boost::lambda with std::find_if Misiu C++ 3 01-31-2007 05:46 PM
Problems mixing boost::lambda::bind and boost::shared_ptr.. Toby Bradshaw C++ 6 06-02-2006 04:12 PM



Advertisments