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

J

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?

#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
 
A

Alf P. Steinbach

* 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
 
J

Jim Langston

Jim Langston said:
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.
 
E

eriwik

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.
 
J

Jacek Dziedzic

Jim said:
Jim Langston said:
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.
 
M

Michiel.Salters

Jacek Dziedzic schreef:
Jim said:
Jim Langston said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top