Why does this stl function call result in an incorrect boolean evaluation? [duplicate]
This question already has an answer here:
c++ vector size. why -1 is greater than zero
3 answers
I was humbly coding away when I ran into a strange situation involving checking the size of a vector. An isolated version of the issue is listed below:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cw = {"org","app","tag"};
int j = -1;
int len = cw.size();
bool a = j>=cw.size();
bool b = j>=len;
std::cout<<"cw.size(): "<<cw.size()<<std::endl;
std::cout<<"len: "<<len<<std::endl;
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
return 0;
}
Compiling with both g++ and clang++ (with the -std=c++11 flag) and running results in the following output:
cw.size(): 3
len: 3
1
0
why does j >= cw.size() evaluate to true? A little experimenting that any negative value for j results in this weird discrepancy.
c++ c++11 stl unsigned signed
marked as duplicate by Community♦ Dec 31 '18 at 3:21
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
c++ vector size. why -1 is greater than zero
3 answers
I was humbly coding away when I ran into a strange situation involving checking the size of a vector. An isolated version of the issue is listed below:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cw = {"org","app","tag"};
int j = -1;
int len = cw.size();
bool a = j>=cw.size();
bool b = j>=len;
std::cout<<"cw.size(): "<<cw.size()<<std::endl;
std::cout<<"len: "<<len<<std::endl;
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
return 0;
}
Compiling with both g++ and clang++ (with the -std=c++11 flag) and running results in the following output:
cw.size(): 3
len: 3
1
0
why does j >= cw.size() evaluate to true? A little experimenting that any negative value for j results in this weird discrepancy.
c++ c++11 stl unsigned signed
marked as duplicate by Community♦ Dec 31 '18 at 3:21
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Read about integral conversions. Note thatcw.zize()returns an unsigned type.
– Pete Becker
Dec 30 '18 at 23:34
cw.size()is unsigned. In the comparison, the negative value ofjgets coerced to a very large positive value.
– Igor Tandetnik
Dec 30 '18 at 23:34
2
Enable additional warnings (-Wall -Wextrafor gcc/clang) and the compiler will likely warn you about stuff like this.
– user10605163
Dec 30 '18 at 23:35
2
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21
add a comment |
This question already has an answer here:
c++ vector size. why -1 is greater than zero
3 answers
I was humbly coding away when I ran into a strange situation involving checking the size of a vector. An isolated version of the issue is listed below:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cw = {"org","app","tag"};
int j = -1;
int len = cw.size();
bool a = j>=cw.size();
bool b = j>=len;
std::cout<<"cw.size(): "<<cw.size()<<std::endl;
std::cout<<"len: "<<len<<std::endl;
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
return 0;
}
Compiling with both g++ and clang++ (with the -std=c++11 flag) and running results in the following output:
cw.size(): 3
len: 3
1
0
why does j >= cw.size() evaluate to true? A little experimenting that any negative value for j results in this weird discrepancy.
c++ c++11 stl unsigned signed
This question already has an answer here:
c++ vector size. why -1 is greater than zero
3 answers
I was humbly coding away when I ran into a strange situation involving checking the size of a vector. An isolated version of the issue is listed below:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cw = {"org","app","tag"};
int j = -1;
int len = cw.size();
bool a = j>=cw.size();
bool b = j>=len;
std::cout<<"cw.size(): "<<cw.size()<<std::endl;
std::cout<<"len: "<<len<<std::endl;
std::cout<<a<<std::endl;
std::cout<<b<<std::endl;
return 0;
}
Compiling with both g++ and clang++ (with the -std=c++11 flag) and running results in the following output:
cw.size(): 3
len: 3
1
0
why does j >= cw.size() evaluate to true? A little experimenting that any negative value for j results in this weird discrepancy.
This question already has an answer here:
c++ vector size. why -1 is greater than zero
3 answers
c++ c++11 stl unsigned signed
c++ c++11 stl unsigned signed
edited Dec 31 '18 at 3:25
nmd
asked Dec 30 '18 at 23:28
nmdnmd
4327
4327
marked as duplicate by Community♦ Dec 31 '18 at 3:21
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Community♦ Dec 31 '18 at 3:21
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
1
Read about integral conversions. Note thatcw.zize()returns an unsigned type.
– Pete Becker
Dec 30 '18 at 23:34
cw.size()is unsigned. In the comparison, the negative value ofjgets coerced to a very large positive value.
– Igor Tandetnik
Dec 30 '18 at 23:34
2
Enable additional warnings (-Wall -Wextrafor gcc/clang) and the compiler will likely warn you about stuff like this.
– user10605163
Dec 30 '18 at 23:35
2
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21
add a comment |
1
Read about integral conversions. Note thatcw.zize()returns an unsigned type.
– Pete Becker
Dec 30 '18 at 23:34
cw.size()is unsigned. In the comparison, the negative value ofjgets coerced to a very large positive value.
– Igor Tandetnik
Dec 30 '18 at 23:34
2
Enable additional warnings (-Wall -Wextrafor gcc/clang) and the compiler will likely warn you about stuff like this.
– user10605163
Dec 30 '18 at 23:35
2
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21
1
1
Read about integral conversions. Note that
cw.zize() returns an unsigned type.– Pete Becker
Dec 30 '18 at 23:34
Read about integral conversions. Note that
cw.zize() returns an unsigned type.– Pete Becker
Dec 30 '18 at 23:34
cw.size() is unsigned. In the comparison, the negative value of j gets coerced to a very large positive value.– Igor Tandetnik
Dec 30 '18 at 23:34
cw.size() is unsigned. In the comparison, the negative value of j gets coerced to a very large positive value.– Igor Tandetnik
Dec 30 '18 at 23:34
2
2
Enable additional warnings (
-Wall -Wextra for gcc/clang) and the compiler will likely warn you about stuff like this.– user10605163
Dec 30 '18 at 23:35
Enable additional warnings (
-Wall -Wextra for gcc/clang) and the compiler will likely warn you about stuff like this.– user10605163
Dec 30 '18 at 23:35
2
2
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21
add a comment |
1 Answer
1
active
oldest
votes
The pitfalls here are signed integral conversions that apply when you compare a signed integral value with an unsigned one. In such a case, the signed value will be converted to an unsigned one, and if the value was negative, it will get UINT_MAX - val + 1. So -1 will be converted to a very large number before comparison.
However, when you assign an unsigned value to a signed one, like int len = vec.size(), then the unsigned value will become a signed one, so (unsigned)10 will get (signed)10, for example. And a comparison between two signed ints will not convert any of the both operands and will work as expected.
You can simulate this rather easy:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
Output:
1
0
unsigned_j: 4294967295
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The pitfalls here are signed integral conversions that apply when you compare a signed integral value with an unsigned one. In such a case, the signed value will be converted to an unsigned one, and if the value was negative, it will get UINT_MAX - val + 1. So -1 will be converted to a very large number before comparison.
However, when you assign an unsigned value to a signed one, like int len = vec.size(), then the unsigned value will become a signed one, so (unsigned)10 will get (signed)10, for example. And a comparison between two signed ints will not convert any of the both operands and will work as expected.
You can simulate this rather easy:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
Output:
1
0
unsigned_j: 4294967295
add a comment |
The pitfalls here are signed integral conversions that apply when you compare a signed integral value with an unsigned one. In such a case, the signed value will be converted to an unsigned one, and if the value was negative, it will get UINT_MAX - val + 1. So -1 will be converted to a very large number before comparison.
However, when you assign an unsigned value to a signed one, like int len = vec.size(), then the unsigned value will become a signed one, so (unsigned)10 will get (signed)10, for example. And a comparison between two signed ints will not convert any of the both operands and will work as expected.
You can simulate this rather easy:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
Output:
1
0
unsigned_j: 4294967295
add a comment |
The pitfalls here are signed integral conversions that apply when you compare a signed integral value with an unsigned one. In such a case, the signed value will be converted to an unsigned one, and if the value was negative, it will get UINT_MAX - val + 1. So -1 will be converted to a very large number before comparison.
However, when you assign an unsigned value to a signed one, like int len = vec.size(), then the unsigned value will become a signed one, so (unsigned)10 will get (signed)10, for example. And a comparison between two signed ints will not convert any of the both operands and will work as expected.
You can simulate this rather easy:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
Output:
1
0
unsigned_j: 4294967295
The pitfalls here are signed integral conversions that apply when you compare a signed integral value with an unsigned one. In such a case, the signed value will be converted to an unsigned one, and if the value was negative, it will get UINT_MAX - val + 1. So -1 will be converted to a very large number before comparison.
However, when you assign an unsigned value to a signed one, like int len = vec.size(), then the unsigned value will become a signed one, so (unsigned)10 will get (signed)10, for example. And a comparison between two signed ints will not convert any of the both operands and will work as expected.
You can simulate this rather easy:
int main() {
int j = -1;
bool a = j >= (unsigned int)10; // signed >= unsigned; will convert j to unsigned int, yielding 4294967295
bool b = j >= (signed int)10; // signed >= signed; will not convert j
cout << a << endl << b << endl;
unsigned int j_unsigned = j;
cout << "unsigned_j: " << j_unsigned << endl;
}
Output:
1
0
unsigned_j: 4294967295
edited Dec 30 '18 at 23:51
answered Dec 30 '18 at 23:45
Stephan LechnerStephan Lechner
28.4k32143
28.4k32143
add a comment |
add a comment |
1
Read about integral conversions. Note that
cw.zize()returns an unsigned type.– Pete Becker
Dec 30 '18 at 23:34
cw.size()is unsigned. In the comparison, the negative value ofjgets coerced to a very large positive value.– Igor Tandetnik
Dec 30 '18 at 23:34
2
Enable additional warnings (
-Wall -Wextrafor gcc/clang) and the compiler will likely warn you about stuff like this.– user10605163
Dec 30 '18 at 23:35
2
These comments should be answers
– twoleggedhorse
Dec 30 '18 at 23:36
Ah, definitely should've had the warnings up as @user10605163 suggested, pointed me right towards the problem.
– nmd
Dec 31 '18 at 3:21