1

Output for the below program is :

dat : 18446721190124690902 892374

dat : 892374 892374

What is happening when I pass variable "a" as pointer ? I expected both functions to print same values.

#include <stdio.h>

void func(unsigned long long * dat) {
        printf("dat : %llu %u \n",*dat,*dat);
}

void func1(unsigned long long dat) {
        printf("dat : %llu %u \n",dat,dat);
}

int main(void)
{
        unsigned int a;
        a = 892374;
        func((unsigned long long *) &a);
        func1((unsigned long long) a);
        return 0;
}
user1662780
  • 61
  • 1
  • 4

4 Answers4

1

You're hitting undefined behaviour because the size of an unsigned int is smaller than an unsigned long long. As far as func is concerned the memory pointed to by dat is 8 bytes long when in actual fact it's only 4 bytes - so it's accessing an extra 4 bytes that contain random values. You're casting it back down to an unsigned int for the %u portion of the printf so it doesn't use the extra 4 bytes and so you're getting the right value.

The second function works properly because it's casting the value to an unsigned long long so the size difference isn't an issue.

Chris Turner
  • 8,082
  • 1
  • 14
  • 18
1

Suppose int is 4 bytes and long long is 8 bytes in your platform. When you cast an integer pointer to a long long pointer, the program will try to read 8 bytes from the address pointed by the pointer.

aneesh jose
  • 381
  • 2
  • 8
1

Technically nobody knows what is happening because your program exhibits undefined behaviour. However, we can make educated guesses based on common architectures e.g. x86 or x86_64.

The first problem is the cast here:

func((unsigned long long *) &a);

You cast the pointer but not the value to which it points. On many common machines, int would be a 32 bit value and unsigned long long is 64 bits. a is 32 bits long but you pass a pointer to a 64 bit block. The 32 bits above a in memory could be anything. This is the reason why the first print prints that really long binary number.

In func1, you correctly cast a so the program will extend a to 64 bits when it puts it on the stack.

In both cases, the format specifier for the last argument of the printf is incorrect. printf assumes it has been passed a 32 bit value and is somehow ignoring the top 32 bits of what has been passed, probably because it is being passed in a 64 bit register. It's undefined behaviour, it can do what it likes.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

In func1 you are copying the value into a long long and so the value is maintained. In func you are copying the memory address and then telling the compiler to just treat it as though it's pointing to 64bits of memory when it's not. It is reading memory you have not set.

The compiler would stop/warn you if you remove the cast when you call it like this:

func(&a);
func1(a);
noelicus
  • 14,468
  • 3
  • 92
  • 111