-std::map.size() reported wrong?

Discussion in 'C++' started by Jim Langston, Dec 4, 2006.

  1. Jim Langston

    Jim Langston Guest

    Expected output of this program is:
    1
    -1
    -1
    -1

    Using Microsoft Visual C++ .net 2003 actual output is:
    1
    4294967295
    4294967295
    4294967295

    Can someone explain why to me?

    #include <string>
    #include <iostream>
    #include <map>

    std::map<int, std::string> Foo;

    int main()
    {
    Foo[1] = "Hello";

    std::cout << Foo.size() << "\n";
    std::cout << -Foo.size() << "\n";
    std::cout << 0 - Foo.size() << "\n";
    std::cout << 0 - (Foo.size()) << std::endl;

    std::string wait;
    std::getline( std::cin, wait );

    } // function main
    Jim Langston, Dec 4, 2006
    #1
    1. Advertising

  2. * Jim Langston:
    > Expected output of this program is:
    > 1
    > -1
    > -1
    > -1
    >
    > Using Microsoft Visual C++ .net 2003 actual output is:
    > 1
    > 4294967295
    > 4294967295
    > 4294967295
    >
    > Can someone explain why to me?


    unsigned

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Dec 4, 2006
    #2
    1. Advertising

  3. Jim Langston

    Jim Langston Guest

    "Jim Langston" <> wrote in message
    news:CETch.367$...
    > Expected output of this program is:
    > 1
    > -1
    > -1
    > -1
    >
    > Using Microsoft Visual C++ .net 2003 actual output is:
    > 1
    > 4294967295
    > 4294967295
    > 4294967295
    >
    > Can someone explain why to me?
    >
    > #include <string>
    > #include <iostream>
    > #include <map>
    >
    > std::map<int, std::string> Foo;
    >
    > int main()
    > {
    > Foo[1] = "Hello";
    >
    > std::cout << Foo.size() << "\n";
    > std::cout << -Foo.size() << "\n";
    > std::cout << 0 - Foo.size() << "\n";
    > std::cout << 0 - (Foo.size()) << std::endl;
    >
    > std::string wait;
    > std::getline( std::cin, wait );
    >
    > } // function main


    Hmm.. I was able to get the expected output this way:
    #include <string>
    #include <iostream>
    #include <map>

    std::map<int, std::string> Foo;

    int main()
    {
    Foo[1] = "Hello";

    std::cout << Foo.size() << "\n";
    std::cout << -static_cast<int>( Foo.size() ) << "\n";
    std::cout << 0 - static_cast<int>( Foo.size() ) << "\n";
    std::cout << 0 - static_cast<int>( (Foo.size()) ) << std::endl;

    std::string wait;
    std::getline( std::cin, wait );

    } // function main

    I can understand why I have to do this, but I don't understand why I should
    have to do this. It is unexpected.

    The actual application was like this:

    float x = (- Models.size() / 2 + ModelCount ) * 10;

    I understand that size() returns an unsigned type, and since it is one, is
    similar to sayign something like: static_cast<unsigned int>( -1 )
    Man, thsi is really a gotcha.
    Jim Langston, Dec 4, 2006
    #3
  4. Jim Langston

    Guest

    On Dec 4, 12:36 pm, "Jim Langston" <> wrote:
    > "Jim Langston" <> wrote in messagenews:CETch.367$...
    > int main()
    > {
    > Foo[1] = "Hello";
    >
    > std::cout << Foo.size() << "\n";
    > std::cout << -static_cast<int>( Foo.size() ) << "\n";
    > std::cout << 0 - static_cast<int>( Foo.size() ) << "\n";
    > std::cout << 0 - static_cast<int>( (Foo.size()) ) << std::endl;
    >
    > std::string wait;
    > std::getline( std::cin, wait );
    >
    > } // function main
    >
    > I can understand why I have to do this, but I don't understand why I should
    > have to do this. It is unexpected.


    To get the behaviour you expec the unsigned int would have to be
    converted to a signed int automagically, however the unsigned int can
    contain values that the signed one can't so to do an automatic
    conversion would be dangerous.

    --
    Erik Wikström
    , Dec 4, 2006
    #4
  5. Jim Langston wrote:
    > "Jim Langston" <> wrote in message
    > news:CETch.367$...
    >> Expected output of this program is:
    >> 1
    >> -1
    >> -1
    >> -1
    >>
    >> Using Microsoft Visual C++ .net 2003 actual output is:
    >> 1
    >> 4294967295
    >> 4294967295
    >> 4294967295
    >>
    >> Can someone explain why to me?
    >>
    >> #include <string>
    >> #include <iostream>
    >> #include <map>
    >>
    >> std::map<int, std::string> Foo;
    >>
    >> int main()
    >> {
    >> Foo[1] = "Hello";
    >>
    >> std::cout << Foo.size() << "\n";
    >> std::cout << -Foo.size() << "\n";
    >> std::cout << 0 - Foo.size() << "\n";
    >> std::cout << 0 - (Foo.size()) << std::endl;
    >>
    >> std::string wait;
    >> std::getline( std::cin, wait );
    >>
    >> } // function main

    >
    > Hmm.. I was able to get the expected output this way:
    > #include <string>
    > #include <iostream>
    > #include <map>
    >
    > std::map<int, std::string> Foo;
    >
    > int main()
    > {
    > Foo[1] = "Hello";
    >
    > std::cout << Foo.size() << "\n";
    > std::cout << -static_cast<int>( Foo.size() ) << "\n";
    > std::cout << 0 - static_cast<int>( Foo.size() ) << "\n";
    > std::cout << 0 - static_cast<int>( (Foo.size()) ) << std::endl;
    >
    > std::string wait;
    > std::getline( std::cin, wait );
    >
    > } // function main
    >
    > I can understand why I have to do this, but I don't understand why I should
    > have to do this. It is unexpected.
    >
    > The actual application was like this:
    >
    > float x = (- Models.size() / 2 + ModelCount ) * 10;
    >
    > I understand that size() returns an unsigned type, and since it is one, is
    > similar to sayign something like: static_cast<unsigned int>( -1 )
    > Man, thsi is really a gotcha.


    I think it will get even worse on systems where size_t is 64-bit
    and int is 32-bit. Then casting to an int will get you into
    trouble if Models.size() is large enough (extremely large,
    admittedly).

    I hope I can be proven wrong :).

    - J.
    Jacek Dziedzic, Dec 4, 2006
    #5
  6. Jim Langston

    Guest

    Jacek Dziedzic schreef:

    > Jim Langston wrote:
    > > "Jim Langston" <> wrote in message
    > > news:CETch.367$...
    > >> Expected output of this program is:
    > >> 1
    > >> -1
    > >> -1
    > >> -1
    > >>
    > >> Using Microsoft Visual C++ .net 2003 actual output is:
    > >> 1
    > >> 4294967295
    > >> 4294967295
    > >> 4294967295
    > >>
    > >> Can someone explain why to me?
    > >>
    > >> #include <string>
    > >> #include <iostream>
    > >> #include <map>
    > >>
    > >> std::map<int, std::string> Foo;
    > >>
    > >> int main()
    > >> {
    > >> Foo[1] = "Hello";
    > >>
    > >> std::cout << Foo.size() << "\n";
    > >> std::cout << -Foo.size() << "\n";
    > >> std::cout << 0 - Foo.size() << "\n";
    > >> std::cout << 0 - (Foo.size()) << std::endl;
    > >>
    > >> std::string wait;
    > >> std::getline( std::cin, wait );
    > >>
    > >> } // function main

    > >
    > > Hmm.. I was able to get the expected output this way:
    > > #include <string>
    > > #include <iostream>
    > > #include <map>
    > >
    > > std::map<int, std::string> Foo;
    > >
    > > int main()
    > > {
    > > Foo[1] = "Hello";
    > >
    > > std::cout << Foo.size() << "\n";
    > > std::cout << -static_cast<int>( Foo.size() ) << "\n";
    > > std::cout << 0 - static_cast<int>( Foo.size() ) << "\n";
    > > std::cout << 0 - static_cast<int>( (Foo.size()) ) << std::endl;
    > >
    > > std::string wait;
    > > std::getline( std::cin, wait );
    > >
    > > } // function main
    > >
    > > I can understand why I have to do this, but I don't understand why I should
    > > have to do this. It is unexpected.
    > >
    > > I understand that size() returns an unsigned type, and since it is one, is
    > > similar to sayign something like: static_cast<unsigned int>( -1 )

    >
    > I think it will get even worse on systems where size_t is 64-bit
    > and int is 32-bit. Then casting to an int will get you into
    > trouble if Models.size() is large enough (extremely large,
    > admittedly).
    >
    > I hope I can be proven wrong :).


    Unlikely - you are right. Basically, if you are doing math in C++, you
    must
    consider the C++ math rules. Unsigned integer math is modulo UINT_MAX.
    If you don't like that, use signed int, and make sure you don't have
    overflows.

    HTH,
    Michiel Salters
    , Dec 5, 2006
    #6
    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. Matthias Hildebrand
    Replies:
    5
    Views:
    7,968
    krogers
    Mar 20, 2012
  2. Peter Jansson
    Replies:
    5
    Views:
    6,305
    Ivan Vecerina
    Mar 17, 2005
  3. Replies:
    1
    Views:
    420
    red floyd
    Dec 21, 2008
  4. Thomas J. Gritzan
    Replies:
    6
    Views:
    1,020
    James Kanze
    Dec 22, 2008
  5. James Kanze
    Replies:
    0
    Views:
    1,999
    James Kanze
    Dec 21, 2008
Loading...

Share This Page