0

I'm trying this example and I don't understand how these values appear. How it's done the bitwise operation if the values are not initialized?

int main() {
  int a, b, c, d;
  d = a % b;
  c = a | b;
  printf("OR: %d", c);
  printf("AND: %d", d);
  return 0;
}
  • 3
    They are bitwise operations. But you should initialize `a` and `b` – Basile Starynkevitch Jan 09 '19 at 18:13
  • 1
    what you have now are junk values . those values are manipulated in your main – H.cohen Jan 09 '19 at 18:15
  • Yes i know but i tried to not initialize the values and the result for OR it's 62 and for AND it's 6 – fallenswor f Jan 09 '19 at 18:15
  • 2
    @fallensworf: If you don't initialize `a` or `b`, then they will contain some random garbage, thus the results of `a|b` and `a%b` (which is a modulus operation, not a bitwise AND operation) will also be random garbage. – John Bode Jan 09 '19 at 18:23

2 Answers2

3

An uninitialized variable contains garbage value, and using it may become undefined behavior. Be scared.

The memory location or register holding these variables have some content (which cannot be predicted in general), even before the bitwise operation. Consider that content as at least random (or "buggy").

BTW, you should enable all warnings and debug info when compiling. With GCC, use gcc -Wall -Wextra -g. Your source code would probably trigger some warning. I recommend to always initialize your automatic variables (perhaps the optimizing compiler would figure out that the initialization is useless, then it skips it, per the as-if rule; but you are sure that the variable has some well known value).

Imagine that you compile and run the same program on some very different computer (with another operating system, another compiler, another processor). You are very likely to observe different program behavior.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Is an uninitialized variable is as good as assigning it to null i.e. `int a = null` ? –  Jan 09 '19 at 21:11
  • 1
    Sorry, your question makes no sense. `null` has no meaning in C, and `NULL` is a pointer, not an `int`; so you won't initialize an `int` variable from a pointer. – Basile Starynkevitch Jan 10 '19 at 05:43
1

Without knowing what complier you are using it is difficult to know what the result will be, but most likely it will either be 0 or some

One of the beautiful things about C is that you can generate assembly language that is (some what) human readable, and using that you can see what your C code will do.

I used an ARM compiler as ARM CPU is a Reduced Instruction Set Computer (RISC) and it's assembly code is a bit easier to read.

To compile you code I ran the instruction

arm-linux-gnueabi-gcc-7 -S -O0 -fverbose-asm  main.c

which generated a main.s file. The -S causes the assembly code to be generated. The -fverbose-asm add the sorce code as comments in assmenly code. And the -O0 keeps that complier from optimizing the code into something harder to read.

Your OR code generates:

@ main.c:7:  c = a | b;
        ldr     r2, [fp, #-8]   @ tmp115, a
        ldr     r3, [fp, #-12]  @ tmp116, b
        orr     r3, r2, r3      @ tmp114, tmp115, tmp116
        str     r3, [fp, #-16]  @ tmp114, c
@ main.c:8:  printf("OR: %d\n",c);
        ldr     r1, [fp, #-16]  @, c
        ldr     r3, .L3+4       @ tmp117,
.LPIC1:
        add     r3, pc, r3      @ tmp117, tmp117
        mov     r0, r3  @, tmp117
        bl      printf(PLT)     @

Your AND code (corrected by replacing % with &) generates:

@ main.c:9:  d = a & b;
        ldr     r2, [fp, #-8]   @ tmp119, a
        ldr     r3, [fp, #-12]  @ tmp120, b
        and     r3, r3, r2      @ tmp118, tmp120, tmp119
        str     r3, [fp, #-20]  @ tmp118, d
@ main.c:10:  printf("AND: %d\n",d);
        ldr     r1, [fp, #-20]  @, d
        ldr     r3, .L3+8       @ tmp121,
.LPIC2:
        add     r3, pc, r3      @ tmp121, tmp121
        mov     r0, r3  @, tmp121
        bl      printf(PLT)     @

To get to your question, not initializing the integers a and b does not change the code. The assembly code generated will used what ever is located in the memory that is pointed to by the frame pointer (fp) minus 8 bytes and the fp minus 12 bytes. If the integers a and b are not set to a particular value then, depending to the compiler, you will get a random value or with some compilers you might always get zero value.

NOTE: It is likely that your C compiler can generate assembly code. The output will most likely be in i386 or X86 assembly code, but you should be able to use it to see how changing your code changes the code that gets generated by your compiler.

Here is an example program that shows (at least with gcc) how not setting a default value can lead to side effects. Here the values passed to one subroutine effect another one.

#include <stdio.h>

int first(int x, int y)
{
    int a, b, c, d;

    a = x;
    b = y;
}

int second()
{
    int a,b,c,d;
    c = a | b;
    printf("OR: %d\n",c);
    d = a & b;
    printf("AND: %d\n",d);
}

int main()
{
    first(5, 3);
    second();
    first(7, 5);
    second();
    return 0;
}

The output being

OR: 7
AND: 1

for 5 and 3 and

OR: 7
AND: 5

for 7 and 5.

G. Allen Morris III
  • 1,012
  • 18
  • 30