Noah said:
sizeof int is 4 on amd64.
long might be a better choice. Is it not specified in the standard as
the word size of the architecture? Oh well, not near by...you'll have
to check.
Or as someone said, void* is supposed to be big enough to hold any
pointer, no? Don't know if it has to be word size by standard or not
though...but it likely is.
The word size is not well defined.
Is the word size 16 or 32 bits on the 68000 CPU?
Defining a word size is a bad thing... Assuming that there is a
"machine word which works for pointers & integers" is really not
portable... That is one reason why the B language is obsolete.
The CPU architecture doesn't dictate a particular pointer size (and
pointer sizes depend on the type pointed-to by the pointer, even if
there are constraints like the fact that all pointers to structures
have the same size & representation).
Remember that "16 bits" x86 compilers had several memory models (most
common were tiny, small, medium, compact, large and huge).
tiny : sizeof(int)==2, sizeof(any object pointer)==2, sizeof(any
function pointer)==2, CHAR_BIT==8
small : same as tiny for pointer sizes (but pointer to object and
pointer to functions lived in two different segments).
medium : sizeof(int)==2, sizeof(object pointer)==2, sizeof(function
pointer)==4
compact : sizeof(int)==2, sizeof(object pointer)==4, sizeof(function
pointer)==2
large : sizeof(int)==2, sizeof(object pointer)==4, sizeof(function
pointer)==4
huge : sizeof(int)==2, sizeof(object pointer)==4, sizeof(function
pointer)==4 (but pointer arithmetic was adjusted and allowed to have
memory blocks greater than 64KB).
Now, the question is: What's the size of a pointer on a 8086 CPU? There
is no answer... It is implementation-defined.... And compiler flags can
even change the size of a pointer.
Note also that sizeof(void*) can be smaller than
sizeof(any_other_pointer), even if a void* pointer can hold any other
pointer.
For instance, a bound-checked implementation on the IA-32 architecture
may use 96 bits pointers for all types except char*, signed char*,
unsigned char* and void* which would be 32 bits (they would not hold
any bound information).
Because char* is not designed to be bound checked:
For instance:
int array[3][3];
int* pi=&array[0][0];
for(size_t i=0;i<5;++i) pi
=0; // undefined behavior : pointer
arithmetic must not go out of the bounds of an array (and the real
static type pointed-to by pi is int[3]).
// This is likely to throw an exception on bound-checked
implementations.
char* pc=static_cast<char*>(static_cast<void*>(array));
for(size_t i=0;i<sizeof(p);++i) *pc=0; // valid
If I remember correctly, in C (and I suppose also in C++) what is
specified is that a char is one byte (thought nothing said about how big
a byte is) and char <= short, short <= int and int <= long. I also seem
to recall that an int should be the "natural" size of the architecture
which would make it 32 on a 32-bit machine and 64 on a 64-bit machine
(and 16 on one of those machines).
Natural size is not well defined.
After thought, 32 bits integer is quite natural on 64 bits platform
(and LP64 is really used by many compilers).
http://www.unix.org/whitepapers/64bit.html
In C there is also a macro telling the number of bits of a char, which
multiplied with sizeof(int) (which returns the number of chars per int)
gave the number of bits of an int.
Yes, CHAR_BIT
C++ too, has this macro.
Note that, as far as I remember, the first C implementation was on the
PDP-11, a 9-bits byte machine.
Anyway, I think that knowing if a machine is 64 bits or 32 bits (since
there is no formal definition of "being 64 bits") is useless.
On the other side, knowing that sizeof(int)==4 or sizeof(int)==8 is
useful... And it is an information useful, independently of
sizeof(void*) or sizeof(struct MyStruct*).