Reputation: 235
In a lot of standard open source code, I see in various places different pointer types being used like :
uint32 fooHash (uint8 *str, uint32 len)
What I don't get is the following: - Why would you want to declare int as uint32, uint8? All of this would run in the userspace itself, so why not just leave as uint itself? Wouldn't portability be an issue later on?
Upvotes: 0
Views: 10915
Reputation: 123448
Also, if you want to run the opensource code on 32bit system, why have a pointer as uint8 *ptr?
uint8_t
is the size of the thing the pointer points to, not the size of the pointer itself; the type of the expression *ptr
is uint8_t
. The type of the object ptr
is uint8_t *
, which is as big as the system needs it to be (32 bits, 64 bits, whatever).
The base type matters when computing pointer arithmetic. Given a pointer declaration
T *p;
the expression p + i
evaluates to the address of the i
'th element of type T
after p
. If T
is int
, then p + i
gives us the address of the i
'th integer following p
. If T
is struct humongous
, then p + i
gives us the address of the i
'th humongous structure following p
. For example:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t *p0 = (uint8_t *) 0x00004000;
uint32_t *p1 = (uint32_t *) 0x00004000;
printf("p0 = %p, (p0 + 1) = %p\n", (void *) p0, (void *)(p0 + 1));
printf("p1 = %p, (p1 + 1) = %p\n", (void *) p1, (void *)(p1 + 1));
return 0;
}
yields the output
p0 = 0x4000, (p0 + 1) = 0x4001 p1 = 0x4000, (p1 + 1) = 0x4004
Pointers need not all be the same size, or have the same representation. For example, in a Harvard architecture, instructions and data are stored in separate areas of memory and may have different sized busses, so object pointers (int *
, char *
, float *
) may be one size (say 8 bits) and function pointers (int (*foo)(void)
) may be a different size (say 16 bits). Similarly, on a word-addressed architecture, a char *
may be a couple of bits wider than other pointer types to specify an offset into the word.
Upvotes: 3
Reputation: 63471
The type of the pointer refers to the datatype it contains, not the size of the pointer itself. All pointers are in fact the same size. ([*] But see the comments below)
If you have a uint8*
, then the pointer refers to an array of uint8
values. This is not the same as uint32*
, which refers to an array of uint32
values.
To answer the other side of your question... The reason that these types are made explicit is because not all compilers agree on the size of an int
. It's a portability thing.
Upvotes: 5
Reputation: 2349
It all depends on the hardware and compiler that you are using.
if you just use an int you can get different sizes. You can also get different sizes on unix vs windows.
All that is required of the compiler is from C99 standard
sizeof(short) <= sizeof(int) <= sizeof(long) < sizeof(long long)
Here is the int type sizes (bits) for Windows platforms:
Type C99 Minimum Windows 32bit
char 8 8
short 16 16
int 16 32
long 32 32
long long 64 64
you should take a look at
the following are guaranteed to be the size they they are named for
int8_t
int16_t
int32_t
int64_t
int8_t
Upvotes: 0
Reputation: 133567
Not all data is meant to be stored as signed int
. A uint8*
is useful for many purposes: strings, binary data (eg a network packet or a piece of a file).
Sometimes you just need uint8 because the range of values you are going to store there resides in [0,256[
.
Don't forget that we are not talking about the type of the pointer but about the type of the pointed data. A pointer is a pointer (which will be of correct size according to the architecture) whatever type it points to.
Upvotes: 2