marlonbymendes's blog

By marlonbymendes, history, 8 years ago, In English

The following piece of code:

    const int N = 10;
    bool can[N];
    memset(can, -1, sizeof can);

    if(can[0] == 0) { // can[0] == false gives same result
        cout << "is zero";
    }
    else {
        cout << "not zero";
    }

Outputs is zero, however I expected it to be not zero.

Using memset like this instead:

    memset(can, 1, sizeof can); // using true instead of 1 gives same result

Outputs not zero as expected. What is going on?

  • Vote: I like it
  • +11
  • Vote: I do not like it

»
8 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

for me, first one prints not zero as expected. I checked it using codeforces custom test as well, again not zero.

basically memset changes every 8 bits of the memory, to the value, so for types like char which are 8-bits, it simply fills the array with the value.

char a[10];
memset(a, 'a', sizeof a);

now all of a is 'a'

  • »
    »
    8 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    It seems that sizeof(char) is defined to be 1. sizeof(bool) however is said to be implementation-defined, wich may explain we have different results. A friend of mine tested the above code, having the same result (is zero) as me and I still have no explanation for what is going on internally.

    • »
      »
      »
      8 years ago, # ^ |
      Rev. 4   Vote: I like it 0 Vote: I do not like it

      The problem with your code is if (can[0] == 0). If you change it to if (!can[0]) I'm pretty sure that it would run as supposed to run.

      Edit:

      and it doesn't matter what sizeof bool is, when you memset it with -1, it's gonna be all set bits cause -1 is 1111111.

      • »
        »
        »
        »
        8 years ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        You're right, i just test it and it worked as I expected using if(!can[0]) and if(can[0]).

        However, the code below prints both not zero and is zero, which blows my mind and I have no idea what is going on internally because bool is defined as 0, which should compare true to == 0.

        const int N = 10;
            bool can[N];
            memset(can, -1, sizeof can);
        
            if(can[0] != 0) {
                cout << "not zero";
            }
            else {
                cout << "is zero";
            }
            cout << "\n";
        
            if(can[0] == 0) {
                cout << "is zero";
            }
            else {
                cout << "not zero";
            }
            cout << "\n";
        
        

        As programmers we expect that something which compares true to (a != 0) should compare false to (a == 0).

»
8 years ago, # |
  Vote: I like it 0 Vote: I do not like it

What's the compiler you've used?

  • »
    »
    8 years ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    From g++ --version: "g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"

    • »
      »
      »
      8 years ago, # ^ |
      Rev. 3   Vote: I like it 0 Vote: I do not like it

      g++ assumes the value of bool is 0 or 1,if you look at the assemly you will find it is actually testing can[0]^1. Here, can[0] is 255 and 255^1=254, which is evaluated as true.

      The above conclusion is based on default config of g++ on several Linux platforms(simplely g++ a.cpp -o a), result may change under different environment.

      • »
        »
        »
        »
        8 years ago, # ^ |
        Rev. 2   Vote: I like it 0 Vote: I do not like it

        I'm sorry but how can 254 == 0 compare true? Or if it's either 1 or 0, how can it compare both true to != 0 and false to == 0? Please read my answer above to HosseinYousefi for details.

        • »
          »
          »
          »
          »
          8 years ago, # ^ |
            Vote: I like it +5 Vote: I do not like it

          Not 254==0, 254 is true.

          if(can[0]==0)->if(can[0]^1)->if(254)

»
8 years ago, # |
  Vote: I like it 0 Vote: I do not like it

You may want to read: Representation of Integers and Reals

For this particular problem, read the section headed with Rumor: In C++, the code “int A[1000]; memset(A,x,sizeof(A));” stores 1000 copies of x into A.