user999755
user999755

Reputation: 235

why use different pointer types?

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

Answers (4)

John Bode
John Bode

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

paddy
paddy

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

nate_weldon
nate_weldon

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

Jack
Jack

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

Related Questions