1

I want to define a great size pointer(64 bit or 128 bit) in gcc which is not depend on platform. I think there is something like __ptr128 or __ptr64 in MSDN.

sizeof(__ptr128) is 16 bytes.
sizeof(__ptr64 ) is 8  bytes.

is it possible?

it can be useful when you use kernel functions in 64 bit OS which requires 8 bytes pointer argument and you have a 32 bit application which uses 32 bits address and you want to use this kernel function.

Mohammad Sheykholeslam
  • 1,379
  • 5
  • 18
  • 35
  • 3
    How exactly are you going to make use of a pointer that is larger than your address space? – user57368 Feb 13 '12 at 14:49
  • 1
    As @adelphus says in his [answer below](http://stackoverflow.com/a/9262508/180174), platform -independent pointer size definition does not make sense. That being said, there is a `__int128` type for 128 bit integers in GCC 4.6 (but not older) – Kimvais Feb 13 '12 at 14:56

4 Answers4

7

Your question makes no sense. Pointers, by definition, are a memory address to something - the size must depend upon the platform. How would you dereference a 128-bit pointer on a hardware platform supporting 64-bit addressing?!

You can create 64 or 128-bit values, but a pointer is directly related to the memory addressing scheme of the underlying hardware.

EDIT

With your additional statement, I think I see what you're trying to do. Unfortunately, I doubt it's possible. If the kernel function you want to use takes a 64-bit pointer argument, it's highly likely to be a 64-bit function (unless you're developing for some unusual hardware).

Even though it's technically possible to mix 64-bit instructions into a 32-bit executable, no compiler will actually let you do this. A 64-bit API call will use 64-bit code, 64-bit registers and a 64-bit stack - it would be extremely awkward for the compiler and operating system to manage arbitrary switching from a 32-bit environment to a 64-bit environment.

You should look at finding the equivalent API for a 32-bit environment. Perhaps you could post the kernel function prototype (name+parameters) you want to use and someone could help you find a better solution.

Just so there's no confusion, __ptr64 in MSDN is not platform independent:

On a 32-bit system, a pointer declared with __ptr64 is truncated to a 32-bit pointer.

adelphus
  • 10,116
  • 5
  • 36
  • 46
  • it can be useful when you use kernel functions in 64 bit OS which requires 8 bytes pointer argument and you have a 32 bit application which uses 32 bits address and you want to use this kernel function. – Mohammad Sheykholeslam Feb 13 '12 at 15:01
  • 1
    So what you _really_ want is a 32/64 bit pointer, not a 128 bit pointer. Which is really just a 64 bit pointer, anyway (with the upper half zero for 32 bits...). Or, _just a pointer_, because on a 32 bit system you can't have a 64 bit pointer that isn't totally bogus, and on a 64 bit system, a pointer is already 64 bits in any case. Which makes the entire endeavour a bit absurd to begin with. Or, if you are paranoid about struct padding/alignment, you might want to wrap a `void*` and a `uint64_t` into an union with appropriate conversion operators. – Damon Feb 13 '12 at 16:39
  • Yep! i think so. but I like to have more details and an example if there is! – Mohammad Sheykholeslam Feb 13 '12 at 16:43
  • PowerPC has an ABI for 64-bit instructions with 32-bit executables, as does MIPS (n32). – Brett Hale Jun 07 '18 at 08:31
0

Can't comment, but the statement that you can't use 64 bit instructions in a "32 bit executable" is misleading since the definition of "32 bit executable" is subject to interpretation. If you mean an executable that uses 32 bit pointers, then there is nothing at all that says you can't use instructions that manipulate 64 bit values while using 32 bit pointers. The processor doesn't know the difference.

Linux even supports a mode where you can have a 32 bit userspace and a 64 bit kernel space. Thus, each app has access to 4GB of RAM, but the system can access much more. This keeps the size of your pointers down to 4 bytes but does not restrict the use of 64 bit data manipulations.

Evan Langlois
  • 4,050
  • 2
  • 20
  • 18
0

I'm late to the party but the question makes quite a lot of sense in embedded platforms.

If you combine a CPU with some additional accelerators in the same SOC, they don't necessarily need to have the same address space or address space size.

For the firmware in the accelerator you would want pointers that cover its address space from the CPU and the accelerator's perspective. They are not necessarily the same size.

For example, with a 64 bit CPU and a 32 bit accelerator, the pointer for the firmware can cover 32 bit long address space and the pointer for CPU covers 64 bit address space. C does not have two or more void * types depending on the address spaces you want to talk to.

People generally solve this by casting void * to uintN_t with N as large as needed and passing this around between different parts of the system.

-1

There is none, because gcc was not designed for embedded architectures. There are architectures where multiple sized pointers exist like for example m16c: ram has 16 bit addresses and rom(flash) has 20 bit addresses in the same address space. The performance and size usage is better for smaller pointers.

nulleight
  • 794
  • 1
  • 5
  • 12
  • A complete [AVR](https://gcc.gnu.org/wiki/avr-gcc) toolchain (an 8-bit processor) would suggest it handles embedded arch just fine, not to mention the many ARM ISAs and platforms that gcc has been ported to. – Brett Hale Jun 07 '18 at 08:26
  • Still it is a hack and architecture specific. Different pointer sized are not handled in a generic way. Each architecture has its own named address spaces, where smaller pointer sizes could be used on any architecture to save space. I still stand by my assertion that gcc was not designed for embedded hardware, that it is used for that, that is another thing. I still can not specify my own pointer size in a type. – nulleight Jun 07 '18 at 09:26
  • See https://gcc-renesas.com/migration-guides/iar-m16cm32c/index.html for example: __far or __data is not supported by gcc, and you cannot make a pointer 20 bit and use another that is 16 bit, because gcc cannot differentiate them, or better to say, there is no simple user interface to specify this in a generic way. – nulleight Jun 07 '18 at 09:29
  • Also if gcc would be designed for embedded, it would have C extensions that would make it aware of Hardware architectures by making pointers include memory region property. For example gcc on AVR will gladly accept data pointer as format in printf_P without warning or anything. – nulleight Jun 07 '18 at 09:51