0

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);
    }
};
phuclv
  • 37,963
  • 15
  • 156
  • 475
Kargath
  • 450
  • 5
  • 15
  • 2
    Left shift of a signed integer value is undefined behaviour according to the C++ standard. Simple as that. You fix it by first casting to unsigned value of the same size or you figure out a different approach which doesn't shift the signed value. – Louis Cloete Nov 25 '21 at 15:22
  • 2
    @LouisCloete `Left shift of a signed integer value is undefined behaviour` Don't you mean "negative integer"? Signed shift is well defined as long as the operands are within allowed domains. – eerorika Nov 25 '21 at 15:37
  • "Cracking the coding interview" is not a pinnacle of C++ coding. Most of the code there is actually terrible. – n. m. could be an AI Nov 25 '21 at 15:38
  • it's already clear from the title: `runtime error` is not something the compiler knows at compile time – phuclv Nov 25 '21 at 15:52
  • For the "stack overflow" problem, you've mistyped the code. It should be `~getNextLarger(~num)`, not calling `getNextSmaller`. – 1201ProgramAlarm Nov 25 '21 at 15:53
  • @1201ProgramAlarm Even after I modify it, it still fails to pass. – Kargath Dec 12 '21 at 09:48

1 Answers1

0

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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 1
    If compilers could detect all UB at compile time, we could solve the halting problem and logic itself would burst into flames. – Beta Nov 25 '21 at 15:54