Is the size of the datatype "int" always equals to the size of a pointer in the c language?
I'm just curious.
Not at all, there is no guarantee that sizeof(int) == sizeof(void*)
. And on Linux/AMD64 sizeof(int)
is 4 bytes, and sizeof(void*)
is 8 bytes (same as sizeof(long)
on that platform).
Recent C standard (e.g. C99) defines a standard header <stdint.h>
which should define, among others, an integral type intptr_t
which is guaranteed to have the size of pointers (and probably even which is reversably castable to and from pointers).
I think that the standard does not guarantee that all pointers have the same size, in particular pointer to functions can be "bigger" than data pointers (I cannot name a platform where it is true). I believe that recent Posix standard requires that (e.g. for dlsym
(3)).
See also this C reference and the n1570 draft C11 standard (or better)
PS. In 2021 I cannot name a common platform with sizeof(long) != sizeof(void*)
. But in the previous century the old intel 286 could have been such a platform.
It is not guaranteed.
And for example, in most 64-bit systems both sizes are usually different.
Even sizeof (int *)
is not guranteed to be equal to sizeof (void *)
.
The only guarantee for void *
size is
sizeof (void *) == sizeof (char *)
== sizeof (signed char *) == sizeof (unsigned char *)
No. Some (mostly older, VAX-era) code assumes this, but it's definitely not required, and assuming it is not portable. There are real implementations where the two differ (e.g., some current 64-bit environments use a 64-bit pointer and 32-bit int).
The C languages gives no guarantees of anything when it comes to integer or pointer sizes.
The size of int
is typically the same as the data bus width, but not necessarily. The size of a pointer is typically the same as the address bus width, but not necessarily.
Many compilers use non-standard extensions like the far
keyword, to access data beyond the width of the default pointer type.
In addition to 64-bit systems, there are also plenty of microcontroller/microprocessor architectures where the size of int and the size of a pointer are different. Windows 3.1 and DOS are other examples.
There's no guarantee of any relation between the sizes of these two types, nor that either can be faithfully represented in the other via round-trip casts. It's all implementation-defined.
With that said, in the real world, unless you're dealing with really obscure legacy 16-bit systems or odd DSPs or such, sizeof(int)
is going to be less than or equal to sizeof(void *)
, and you can faithfully convert int
values to void *
to pass them to interfaces (like pthread_create
) that take a generic void *
argument to avoid wasteful allocation and freeing of memory to store a single int
. In particular, if you're using POSIX or Windows interfaces already, this is definitely a safe real-world assumption to make.
You should never assume void *
can be faithfully represented in int
(i.e. casting a pointer to int
and back). This does not work on any popular real-world 64-bit systems, and the percentage of systems it works on is sure to plummet in the near future.
No. Pointer types do not have to be the same size or representation as integer types. Here are a few relevant sections from the C language standard (online draft available here):
6.2.5 Types
...
27 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.39) Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.
...
39) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
...
6.3.2.3 Pointers
...
5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.56)
6 Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
...
56) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
No, it doesn't have to be, but it's usually the case that sizeof(long) == sizeof(void*)
.