ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Okay, so I know that we cannot rely on 'int' to have any particular size. If you need it to be exactly 32 bits, use int_32_t (or the like).
Here's my question - what if I need a type whose size is exactly equal to the word size of the processor? On a 32-bit machine, it should be 32 bits, 64 on 64-bit, 8 bits on a little PIC, etc.
Is 'int' guaranteed to be the word size? I know it usually works out that way, but I'm really looking for portability.
Here's my question - what if I need a type whose size is exactly equal to the word size of the processor? On a 32-bit machine, it should be 32 bits, 64 on 64-bit, 8 bits on a little PIC, etc.
Word size (at least in this context) is generally the sizeof(void*). By the C standard, the types:
Code:
intptr_t
and
Code:
uintptr_t
Satisfy should this requirement. Notice that these types are optional by the C99 standard, required by the POSIX standard, used by the Windows API (so presumably required by Win32), but not in the current C++ standard. They will, by most predictions be in C++0x (the next C++ standard).
That's exactly what int is supposed to mean, the native CPU word size. I'm not sure, but x86_64 uses a 32-bit int for backwards compatibility, but in that case you could kind of see that processor as having two native word sizes, for some warped definition of "native".
That's exactly what int is supposed to mean, the native CPU word size. I'm not sure, but x86_64 uses a 32-bit int for backwards compatibility, but in that case you could kind of see that processor as having two native word sizes, for some warped definition of "native".
Are you saying a 32-bit compiler on a 64-bit machine will give you a 64-bit int? I use 32-bit Slack 12 on AMD 64 and I have a pointer size of 32.
As I understand the distinction, the x86 / x86_64 is a special case, because the designers of x86_64 intentionally made it backwards compatible. If my understanding is correct, one can run (on x86_64 hardware) a 32-bit program on a 32-bit OS, a 32-bit program on a 64-bit OS, and a 64-bit program on a 64-bit OS. If the OS is 32 bit, then 32 bits is indeed the size I want.
Essentially, what I really want is the largest size such that I can be relatively certain that there is a pretty direct mapping between my code and assembly. I'm trying to move data around memory as fast as I can. If I use a type too small, the compiler is doing a bunch of work to adjust the size of my variables to match word size/alignment/etc. If it's too big, the compiler will generate code to split it into two smaller types, which is no good either. I would just write it in assembly, except that I would like it to be portable.
EDIT:
And yes, I know about memcpy(), memmove(), and friends. I'm doing some pretty low-level stuff, and I need a bit more flexibility, such as the ability to bail out midway, etc.
Last edited by PatrickNew; 02-19-2008 at 04:11 PM.
Are you saying a 32-bit compiler on a 64-bit machine will give you a 64-bit int?
It depends on the arch. If you have an ILP64 arch, then yes, but for an LP64 arch, no (this is by definition what ILP and LP mean). On *nix, x86-64 is LP64, but on windows x86-64 is LLP64 (in which case both int and long are 32 bits, but long long is 64 bits).
Quote:
Originally Posted by PatrickNew
As I understand the distinction, the x86 / x86_64 is a special case, because the designers of x86_64 intentionally made it backwards compatible. If my understanding is correct, one can run (on x86_64 hardware) a 32-bit program on a 32-bit OS, a 32-bit program on a 64-bit OS, and a 64-bit program on a 64-bit OS.
I think this is true of other arches such as ppc64 vs. ppc and sparc64 vs. sparc32.
Also, there are other things to take into account besides pointer size. For example, some arches have vector ops which allow for operations on two to four intptr_t’s at a time (e.g., SSE for x86 and altivec for ppc).
Btw, I forgot to say that most modern 64-bit Unix arches use the LP64 model (this includes sparc64, ia64, ppc64, ALPHA, HPPA, and x86-64). The only ILP64 machines I can think of are Cray-variants.
As I understand the distinction, the x86 / x86_64 is a special case, because the designers of x86_64 intentionally made it backwards compatible.
There's also the fact that
char = 8 bit
short = 16 bit
int = 32 bit
long = 64 bit
gives a nice neat one-to-one correspondence between integer sizes and C keywords. If int were 64-bits, then you'd need a name for int32_t: "short" would work, but then what would you call int16_t? "short short"?
Maybe on your machine, but a quick test program assures me that on mine, long is 32 bit. Now, a long long is guaranteed to be 64 bits, but none of the others are guaranteed.
Here's a trivia question for anyone who knows. char is not required to be 8 bits, is it currently (within the last 15 years) implemented as anything else?
I believe it's been implemented as 7 bits. AFAIK unsigned char needs to be 8 bits, at least in C++. Could be wrong.
ta0kira
signed char, unsigned char and char all have a sizeof one defined in the C++ standard.
edit:
And just for confirmation
Quote:
The sizeof operator yields the number of bytes in the object representation of its operand. The operand
is either an expression, which is not evaluated, or a parenthesized type-id. The sizeof operator shall not
be applied to an expression that has function or incomplete type, or to an enumeration type before all its
enumerators have been declared, or to the parenthesized name of such types, or to an lvalue that designates
a bit-field. sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the
result of sizeof applied to any other fundamental type (3.9.1) is implementation-defined. [Note: in particular,
sizeof(bool) and sizeof(wchar_t) are implementation-defined.69) ] [Note: See 1.7 for
the definition of byte and 3.9 for the definition of object representation. ]
Maybe on your machine, but a quick test program assures me that on mine, long is 32 bit. Now, a long long is guaranteed to be 64 bits, but none of the others are guaranteed.
I don’t think Dan meant that was unconditionally true. He meant that if it were true (i.e., an LP64 arch), then there would be a nice 1-1 correspondence between standard C integer types and common integer sizes.
Btw, long long is guaranteed to be at least 64 bits.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.