DonMushroom DonMushroom - 9 months ago 58
C++ Question

Check if a number is odd in c++. Strange behaviour of code

I am a teaching assistant for computer science and one of my students submitted the following code to check whether an integer is odd or even:

int is_odd (int i) {
if((i % 2 == 1) && (i % 2 == -1));

Surprisingly (at least for me) this code gives correct results. I tested numbers up to 100000000, and I honestly cannot explain why this code is behaving as it does.

We are using gcc v6.2.1 and c++

I know that this is not a typical question for so, but I hope to find some help.

Answer Source

Flowing off the end of a function without returning anything is undefined behaviour, regardless of what actually happens with your compiler. Note that if you pass -O3 to GCC, or use Clang, then you get different results.

As for why you actually see the "correct" answer, this is the x86 assembly which GCC 6.2 produces at -O0:

    push    rbp
    mov     rbp, rsp
    mov     DWORD PTR [rbp-4], edi
    mov     eax, DWORD PTR [rbp-4]
    shr     edx, 31
    add     eax, edx
    and     eax, 1
    sub     eax, edx
    cmp     eax, 1
    pop     rbp

Don't worry if you can't read x86. The important thing to note is that eax is used for the return value, and all the intermediate calculations for the if statement use eax as their destination. So when the function exits, eax just happens to have the result of the branch check in it.

Of course, this is all a purely academic discussion; the student's code is wrong and I'd certainly give it zero marks, regardless of whether it passes whatever tests you run it through.