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

Discussion in 'C++' started by Unknownmat, Jul 13, 2008.

  1. Unknownmat

    Unknownmat Guest

    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
    Unknownmat, Jul 13, 2008
    #1
    1. Advertising

  2. Unknownmat

    Unknownmat Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    > 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
    Unknownmat, Jul 13, 2008
    #2
    1. Advertising

  3. Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    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
    Christian Hackl, Jul 14, 2008
    #3
  4. 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.)
    Juha Nieminen, Jul 14, 2008
    #4
  5. Unknownmat

    James Kanze Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    On Jul 14, 4:51 pm, 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',


    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:
    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
    James Kanze, Jul 14, 2008
    #5
  6. Unknownmat

    Unknownmat Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    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
    Unknownmat, Jul 14, 2008
    #6
  7. Unknownmat

    Unknownmat Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    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
    Unknownmat, Jul 14, 2008
    #7
  8. Unknownmat

    Unknownmat Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    On Jul 13, 3:42 pm, Unknownmat <> 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
    Unknownmat, Jul 14, 2008
    #8
  9. Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    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.)
    Juha Nieminen, Jul 14, 2008
    #9
  10. Unknownmat

    James Kanze Guest

    Re: Unexpected compiler behavior relating to size_t and boost -Visual Studio 2005.

    On Jul 14, 7:42 pm, Juha Nieminen <> 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:
    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
    James Kanze, Jul 15, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Rotstein
    Replies:
    1
    Views:
    475
    Scott M.
    Dec 31, 2005
  2. Replies:
    0
    Views:
    1,182
  3. Alex Vinokur
    Replies:
    9
    Views:
    764
    James Kanze
    Oct 13, 2008
  4. RichardOnRails
    Replies:
    4
    Views:
    3,883
    RichardOnRails
    Apr 18, 2010
  5. Alex Vinokur
    Replies:
    1
    Views:
    561
Loading...

Share This Page