Search code examples
c++runtime-errorbit-manipulationbit-shift

runtime error: left shift of negative value -1


In fact I am trying this question:

5.4 in 《Cracking the coding interview:189 programming questions and solutions,fifth edition》

the question is:

Given a positive integer, print the next smallest and the next largest number that have the same number of 1 bits in their binary representation.

There is an exact same question, but the answers are all wrong. Moreover, the purpose of my question is to understand why the code cannot pass the ub checker, not just to get ideas for solving the problem.

0

What does "last executed input" mean on leetcode? Is it an example of the input that caused the error, and if so, why are there no warnings from the three compilers, even if I turn on all -Wall?

1

Why is the book wrong? Here is the code from the book:


class Solution {
public:
    int getNext(int n)
    {
        int c = n;
        int c0 = 0;
        int c1 = 0;
        while (((c & 1) == 0) && (c != 0))
        {
            c0++;
            c >>= 1;
        }
        while ((c & 1) == 1)
        {
            c1++;
            c >>= 1;
        }
        if (c0 + c1 == 31 || c0 + c1 == 0) { return -1; }
        int p = c0 + c1;
        n |= (1 << p);
        n &= ~((1 << p) - 1);
        n |= (1 << (c1 - 1)) - 1;
        return n;
    }
    int getPrev(int n)
    {
        int temp = n;
        int c0 = 0;
        int c1 = 0;
        while ((temp & 1) == 1)
        {
            c1++;
            temp >>= 1;
        }
        if (temp == 0)return -1;
        while (((temp & 1) == 0 )&& (temp != 0))
        {
            c0++;
            temp >>= 1;
        }
        int p = c0 + c1;
        n &= ((~0) << (p + 1));
        int mask = (1 << (c1 + 1)) - 1;
        n |= mask << (c0 - 1);
        return n;
    }
    vector<int> findClosedNumbers(int num) {
        int m = getNext(num);
        int n = getPrev(num);
        return {m,n};
    }
};

The error output is

Line 43: Char 14: runtime error: left shift of negative value -1 (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:53:14

I find this and it said "Left Shifting a negative value is Undefined Behavior"

But why I used all the Wall flags I can think of at https://godbolt.org/, but I didn't get any prompts. Is there some flag to show this just like the UndefinedBehaviorSanitizer?

2.

Someone's answer can't pass

The link mentioned in this answer cannot pass lc, what's the problem with it?

code:


class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        int m = getNextLarger(num);
        int n = getNextSmaller(num);
        return { m,n };
    }
    int getNextLarger(int num) {
        if (num == 0 || num == -1)
            return num;

        // (1) add 1 to the last set bit
        int largeNum = num + (num & ~(num - 1));

        // (2) move the changed bits to the least significant bits. (right side)
        int flipBits = num & ~largeNum;
        int lastBits = 0;
        while (flipBits != 0) {
            flipBits &= flipBits - 1;
            lastBits <<= 1;
            lastBits |= 1;
        }
        lastBits >>= 1;

        // (2.1) move bits to maintain the same number of set bits.
        largeNum |= lastBits;
        return largeNum;
    }
    //Unhandled exception at 0x0033F4B9 in leetcode.exe: 0xC00000FD: Stack overflow 
    int getNextSmaller(int num) {   //with num=2
        return ~getNextLarger(~num);
    }
};

Solution

  • why the func can passed in msvc, clang, and gcc ,but just cannot pass the UndefinedBehaviorSanitizer?

    Because the compiler didn't know at compile time, what value the operand would be at runtime. If compilers were able to detect all UB at compile time, then UB sanitisers wouldn't exist since they would be unnecessary.