Блог пользователя marlonbymendes

Автор marlonbymendes, история, 7 лет назад, По-английски

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?

  • Проголосовать: нравится
  • +11
  • Проголосовать: не нравится

»
7 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

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'

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    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.

    • »
      »
      »
      7 лет назад, # ^ |
      Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

      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.

      • »
        »
        »
        »
        7 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

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

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

What's the compiler you've used?

  • »
    »
    7 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

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

    • »
      »
      »
      7 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      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.

»
7 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

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.