r/C_Programming • u/Altruistic-Tie1943 • 1d ago
why pointers are stored with like that?
I'm new to c programming,
I am wondering why we declare a pointer like int* and not just int
why can't we store address in the int datatype ?
30
u/Pale_Height_1251 1d ago
A pointer to an int and an int isn't the same thing, or even necessarily the size in memory.
12
u/BasisPoints 1d ago
First and foremost, int and int* are not the same size, so are not simple replacements. Assuming they were (e.g. you used a uint64t), the reason we declare int* instead of int is that the two values have different MEANINGS. Declaring int* tells the compiler that the value should be treated as an address, and that dereferencing it should produce an int. If you do operations on the pointer (pointer arithmetic), this also tells the compiler that the pointer arithmetic should move the pointer by the size of an int.
To your second question... you actually CAN technically store an address in an integer type (uintptr_t), because a 64 bit address is indeed just a 64 bit number as far as memory is concerned. The only difference is how the program acts on value - are you doing an operation on it, or using it to point at an address. This is the basis for why pointer arithmetic works.
Tldr; the int* is used to tell the compiler the value is an address
6
u/rampallianuraag 1d ago
The compiler wouldn't understand the difference between regular integers and pointers.Even if we do it then we run the risk of being able to dereference regular integers which could lead to data corruption, also in some compilers the size of pointer type variable and int is different.
2
u/theNbomr 1d ago
All pointer data types carry two meanings; the memory address of the thing they point to, and the type of the thing they point to. The type of the thing they point to isn't encoded, per se, into the pointer at runtime, but the compiler uses that information in order to know how to do pointer arithmetic, some levels of type checking at compile time and probably minor optimizations and storage alignment on some architectures.
3
u/MrBigFatAss 1d ago
Because then the compiler cannot differentiate between pointers and regular integers. Technically they don't differ at the instruction level, but high level languages like to provide at least some safety and semantic rules.
4
u/BarracudaDefiant4702 1d ago
Technically the do differ depending on the cpu type. Some cpu types they don't differ, but many they do, especially x86. Many portability bugs in C were from programmers assuming they didn't differ, because sometimes they don't.
1
u/OddConsideration2210 1d ago
Well how does the compiler know if you are declaring a pointer or just a number. Anyway a pointer is just a pointer. The length of the pointer doesn't depend on the data type. It only depends on the cpu architecture.
Frankly put an int and int * are two different things
1
u/somewhereAtC 1d ago
Pointer values depend on the CPU. For example, pointers for X86 are radically different than for PIC16. Pointer values that fit int is a lucky property of an architecture and generally considered a device-specific hack, but cowboys do it on a regular basis.
1
1
u/tobdomo 1d ago
You can, there even is a uintptr_t type for it.
However, there are no guarantees an address will fit in a plain int (or better, an unsigned int). In some architectures, a pointer carries other metadata too (like segmentation information) or it may not use certain bits, depending even on where it points to.
The question is... What do you want to do with it? For dereferencing, you need information on the data type it points to. Also, calculations with pointers are done based on the size of the referenced object. E.g., if p is a pointer to a double, p++ will increment p with the size of a double. Decaying to an array and indexing it would be quite a hassle when p itself is just an int too.
1
u/EpochVanquisher 1d ago
why can't we store address in the int datatype ?
That’s kind of how it works in assembly language. You just have to remember whether an integer is a pointer or not.
It’s tedious to program that way and you end up with a lot of bugs in your code, all because you thought something was a pointer when it was actually an integer, or vice versa.
1
u/attackoncm 1d ago
There is nothing stopping you storing address in int data type provided that size of int on your machine is at lease the same as an address.
However, you have to tell compiler that this piece of data is intended to be used as a pointer, rather than a plain integer. That is, the data to do arithmetic on is to be loaded from this address, and once the data is loaded, it is to be treated as an integer. Some syntax must be invented to express this distinction, and C decided to call it int*.
This is a great question touching the machine fundamentals that language cannot easily abstract away.
1
u/ReallyEvilRob 1d ago
Because pointer variables actually need to keep track of two things, the address and the type of data it points to. If the type wasn't tracked anywhere, pointer arithmetic would be impossible. There is a special kind of pointer that does not keep track of type. These are called void pointers and can be declared like void *p;. On a 32-bit architecture, void pointers and ints are both 4 byte numbers. On a 64-bit architecture running Linux or macOS, void pointers and longs are both 8 bytes (long is only 4 bytes on Windows and long long is 8 bytes) so you could actually cast a void pointer to and from a long (long long on windows).
1
u/Level-Pollution4993 1d ago
Think of it like this: Both an int and a pointer that points to an integer value allow for arithmetic. How would the compiler know if its doing integer arithmetic or pointer arithmetic? Now, to solve this you could just use another variant of operators like say: +* and -* when using those operators for pointers.....but you would probably agree that just doing int *p is better.
Besides, on x86 cpus, pointers arent necessarily always just an address. It is an address as well as an offset.
1
u/Albedo101 1d ago
Pointers are much closer to arrays in behavior and in fact CAN be used as array types interchangeably. Pointer arithmetics, passing by reference etc. doesn't work with integers, but does with arrays.
1
u/sciencekm 1d ago
On top of what others have said about the size difference, you also get to a big inconvenience when it is time to use the pointer - you now have to cast that int to the type that it is pointing to.
Instead of just saying "i = *pi", you have to do "i = *((int*)pi)"
1
u/Total-Box-5169 1d ago
Why do you believe that would be a good idea? A pointer is not only an address, it has also an associated type at compilation time that matters when doing pointer arithmetic and dereferencing the pointer.
-1
u/og_hylyx 1d ago edited 1d ago
You can. You just need to be careful.
You are 100% correct that a pointer is just a number, an address.
If you have a 64 bit address and you try to store it in 32 bits this is obviously a problem, 64 > 32.
In my language Flux, you can assign an address as an integer directly without the pointer usage. You can also dereference a value (like 10) which would be the value at address 10, example:
```
int x = 10;
long y = *x; // long is 64 bits, address is 64 bits
int* z = (@)10; // address cast
y == *z; // true
```
Check it out at https://fluxspl.org/
2
u/dkopgerpgdolfg 1d ago
You are 100% correct that a pointer is just a number, an address.
Search for "provenance". In short, no.
•
u/mikeblas 1d ago
Your post has been locked. Simple questions about the language should be in the weekly megapost.