Significance of pointer data types
In this article, let’s understand the Effect of using different pointer data types on pointer operations. We will discuss this by taking an example.
In the IDE, let’s write some code. First, our code will have one global variable of type long long int. Let me type long long int, and the variable is g_data. And I initialize this variable with 8 bytes of long data. I would write in hex. 0xFFFEABCD11112345 → This is 8 bytes of long data.
After that, I create a pointer variable of type “char*” and give the name pAddress1. char* pAddress1;
Remember that some people also write this pointer variable definition like this → char *pAddress1; So, they move this asterisk(*).
Please note that both these syntaxes are correct. So, these 2 definitions are identical.
In most of the books and most of the time, you actually find this type char *pAddress1, rather than this type char* pAddress1; That’s why from this article onwards, I would like to use char *pAddress1; There is nothing wrong in using previous pointer definition syntax. But I don’t want to confuse you with books and other literature. That’s why I’m going to stick with this convention.
After that, I store the address of the pAddress1 variable. pAddress1 = &g_data;
#include<stdio.h> long long int g_data = 0xFFFEABCD11112345; int main(void) { char *pAddress1; pAddress1 = &g_data; return 0; }
If you try to compile this, you’ll see a warning here, as shown in Figure 1.
The compiler is saying that there is a type mismatch.
Why?
Because g_data is of type long long int. &g_data is of type long long int*. But pAddress1 of type char*. So, LHS and RHS types are not matching. That’s why there is a warning.
So, to suppress the warning, you can just typecast &g_data pointer with char*, as shown in Figure 2. This is what we call explicit casting. Now it is fine.
Here &g_data is a pointer of type char* and pAddress1 is a pointer variable of type char*, and both are matching. So, there is no warning.
#include<stdio.h> long long int g_data = 0xFFFEABCD11112345; int main(void) { char *pAddress1; pAddress1 = (char*)&g_data; return 0; }
After that, I print the address and the value. So, just observe this printf(“Value at address %p is : %x\n”, pAddress1, *pAddress1);
Let’s print the address, so %p. I print in hex, so %x. I’m going to print the pAddress1 pointer variable and the value which is stored at the pAddress1 pointer. For that, I have to use *pAddress1.
#include<stdio.h> long long int g_data = 0xFFFEABCD11112345; int main(void) { char *pAddress1; pAddress1 = (char*)&g_data; printf("Value at address %p is : %x\n",pAddress1,*pAddress1); return 0; }
Let’s see what the result will be. Let’s run this code. So, the value at address 0000000000403010 is an address of g_data variable is 45.
Observe *pAddress1. When you dereferenced this pointer variable, it printed 1 byte of data, not 2, not 3, not 4, not 8. It just printed only 1 byte of data, that is because its type is char*. So, it’s supposed to fetch only 1 byte of data from that address. That’s why only 1 byte is printed here. That is 45. The first byte is printed.
Let’s create another pointer variable, pAddress2. This time, I’m going to use int*. And again, let’s do the same thing, as shown in Figure 4.
#include<stdio.h> long long int g_data = 0xFFFEABCD11112345; int main(void) { char *pAddress1; pAddress1 = (char*)&g_data; printf("Value at address %p is : %x\n",pAddress1,*pAddress1); int *pAddress2; pAddress2 = (int*)&g_data; printf("Value at address %p is : %x\n",pAddress2,*pAddress2); return 0; }
Let’s see what the result will be. Let’s run this code. Now, the value at address 0000000000403010 is an address of g_data variable is 11112345. You are dereferencing an int* pointer variable. So, that’s the reason this operation is now yielding 4 bytes.
That means, if you want to read 4 bytes at a time from a memory location, then use int*. If you want to read only 1 byte from the memory location, then use char*, and if you want to read 8 bytes at a time from the memory location, then you use long long int*.
Now let’s use short. Let’s create another pointer variable, pAddress3. short means short int. Let’s do the same thing, as shown in Figure 5.
And after that, I create one more block long long int or long long; you can use long long. Both are the same. Let’s create another pointer variable, pAddress4. Now, let’s print, so here actually pAddress4 will yield 8 bytes of data from the memory location. That’s why I have to change this format specifier to support 8 bytes. So, that is %I64X. The code is shown below.
#include<stdio.h> long long int g_data = 0xFFFEABCD11112345; int main(void) { char *pAddress1; pAddress1 = (char*)&g_data; printf("Value at address %p is : %x\n",pAddress1,*pAddress1); int *pAddress2; pAddress2 = (int*)&g_data; printf("Value at address %p is : %x\n",pAddress2,*pAddress2); short *pAddress3; pAddress3 = (short*)&g_data; printf("Value at address %p is : %x\n",pAddress3,*pAddress3); long long *pAddress4; pAddress4 = (long long*)&g_data; printf("Value at address %p is : %I64x\n",pAddress4,*pAddress4); return 0; }
Let’s see what the result will be. Let’s run this code. The first one printed only 1 byte, the second printed 4 bytes of data, and the third printed 2 bytes of data because it is short. So, all these values are getting fetched from 0000000000403010 this address which happens to be the address of the g_data variable. And when you do long long int*, we can see that 8 bytes are fetched.
That’s how changing this pointer data type affects the behavior of the operation that you carry out on the pointer variable. So, all these are read operations; you are reading from the pointer.
Here, observe one thing, so even if you drop this char* (explicit casting), the result will be the same. But the thing is, the compiler will issue a warning. So, this warning actually is not dangerous, but that doesn’t mean that you should ignore that. You should resolve that warning.
But, here, the compiler is just saying there is a type mismatch, but there is no information loss here. Because of the size of &g_data, this entity is 8 bytes, and the memory reserved for the pAddress1 variable is also 8 bytes. So, a 8 byte pointer is stored in 8 bytes of memory space. So, that is perfectly fine. There is no information loss. But it is always good to maintain the same data types on the left-hand side as well as on the right-hand side. That’s why it is better to typecast explicitly. Just to make sure that the data types of LHS and RHS are the same.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1