Search code examples
cfor-loopprintfbitwise-operators

C Program with Bitwise Operators Only Functions Correctly with Debug Statements


I am trying to solve this challenge:

Task: Given set S = {1, 2, 3, ...n}, find:

  • the maximum value of a & b, which is less than a given integer k, where a and b are two integers from set s.
  • the maximum value of a | b, which is less than a given integer k, where a and b are two integers from set s.
  • the maximum value of a ^ b, which is less than a given integer k, where a and b are two integers from set s.

Input Format: The only line contains 2 space-separated integers, n and k, respectively.

I've written this C program to try to solve it.

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

void calculate_the_maximum(int n, int k) {
    int i, j = 1;
    int maxAND, maxOR, maxXOR = 0;
    int AND, OR, XOR = 0;

    for (i = 1; i <= n; i++) {
        for (j = i + 1; j <= n; j++) {
            AND = (i & j); OR = (i | j); XOR = (i ^ j);
            if (AND > maxAND && AND < k) { maxAND = AND; }
            if (OR > maxOR && OR < k) { maxOR = OR; }
            if (XOR > maxXOR && XOR < k) { maxXOR = XOR; }
        }
    }

    printf("%d\n%d\n%d", maxAND, maxOR, maxXOR);
}

int main() {
    int n, k;

    scanf("%d %d", &n, &k);
    calculate_the_maximum(n, k);

    return 0;
}

This seems to me like it should work, unfortunately, it prints out

2
24
3

instead of my expected

2
3
3

Even weirder, sometimes the program prints out a seemingly random number for maxAND, and will look like

1910024400
24
3

Here's the doozy: the program prints out what I expect every time when I include debug statements. If I add this

printf("I: %d J: %d OR: %d\n", i, j, OR);
at line 13, the program now prints out

I: 1 J: 2 OR: 3
I: 1 J: 3 OR: 3
I: 1 J: 4 OR: 5
I: 1 J: 5 OR: 5
I: 2 J: 3 OR: 3
I: 2 J: 4 OR: 6
I: 2 J: 5 OR: 7
I: 3 J: 4 OR: 7
I: 3 J: 5 OR: 7
I: 4 J: 5 OR: 5
2
3
3

Which is exactly what I would expect. Any ideas why this program only outputs what I expect with the inclusion of extra printf's?


Solution

  • In your definition of the variables

    int maxAND, maxOR, maxXOR = 0;
    

    you initialize only maxXOR with 0, but maxAND and maxOR remain uninitialized. Accessing such values later leads to undefined behaviour. Thats what you observe.

    Write ...

    int maxAND = 0, maxOR = 0, maxXOR = 0;
    int AND = 0, OR = 0, XOR = 0;
    

    or something like that, and it should work consistently.

    Note that you must not rely on the compiler to "assign" uninitialized variables the value 0; it may happen, maybe if you build without optimizations, but this behaviour may change in unpredictable ways, sometimes just by adding another completely unrelated variable. Accessing uninitialized variables is always "undefined behaviour".