Why does this stl function call result in an incorrect boolean evaluation? [duplicate]












-1
















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.










share|improve this 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 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






  • 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






  • 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
















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.










share|improve this 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 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






  • 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






  • 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








-1









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.










share|improve this question

















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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






  • 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






  • 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





    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






  • 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






  • 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












1 Answer
1






active

oldest

votes


















2














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





share|improve this answer
































    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    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





    share|improve this answer






























      2














      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





      share|improve this answer




























        2












        2








        2







        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





        share|improve this answer















        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






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 30 '18 at 23:51

























        answered Dec 30 '18 at 23:45









        Stephan LechnerStephan Lechner

        28.4k32143




        28.4k32143















            Popular posts from this blog

            Mossoró

            Error while reading .h5 file using the rhdf5 package in R

            Pushsharp Apns notification error: 'InvalidToken'