0

For example if an architecture supports nibble length instructions but data is byte aligned, will:

void *PointerToAnything;

work? In other words, can the compiler handle this?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
ChrisKW
  • 19
  • 2
  • 3
    Not sure I understand your scenario. Your machine could have say a function's instructions start in the middle of a byte? – Mat Feb 14 '20 at 09:22
  • Yes, C can be implemented on architectures where instructions are aligned to half-byte boundaries. – Eric Postpischil Feb 14 '20 at 10:57
  • There is no “the compiler”. Every compiler is a piece of software written by one or more people. A compiler could be written for this. There are architectures that bind two instructions into one word, and there are compilers for them. – Eric Postpischil Feb 14 '20 at 11:00
  • 1
    Even code-pointers cannot point to arbitrary machine-instructions, only to function-entry-points. Even on your nibble-orianted platform, the standard might define that function entry-points have to be byte-aligned. – Lorinczy Zsigmond Feb 14 '20 at 15:30

1 Answers1

4

In C, it is impossible to access data elements in units smaller than 8 bits, as the smallest possible type is char, which has CHAR_BIT bits, which is 8 at least. Bitfields are an exception, but don't allow pointers to their members; a data-pointer with sub-(8-)byte-precision can not exist in C.

However, instructions (and therefore functions) might be stored differently, and function-pointers could have sub-byte-precision. In general, function pointers and data pointers are not interchangeable, so you can not (correctly) store such a function pointer in a void* pointer. C does not support accessing the machine code anyways, so there would be no support for accessing instructions that have sub-byte-alignment and/or size.

Even on platforms with at least byte-instruction size & alignment, function pointers and data pointers might not be interchangeable, as function pointers might be larger or smaller than data pointers (imagine a system with 256 RAM bytes for data, and 64kB flash bytes for program memory). Therefore, C does not guarantee that void* can point to everything. However, some platforms such as POSIX do explicitly allow this, to allow e.g. dlsym() to work.

Erlkoenig
  • 2,664
  • 1
  • 9
  • 18
  • As a data point, the old IBM AS/400 systems had (have? they appear to still be in use) 16-byte (128 bit) `void *` and 128-byte (1024-bit) `void (*)()` (based on recollection, so this could well be wrong—the main thing I recall was the differing sizes). – torek Feb 15 '20 at 01:15
  • 1
    Interesting... Another thought: For small microcontrollers, (flash) program memory is usually larger than (RAM) data memory, mostly for economic reasons. However, for desktop and server systems, where both are in RAM anyways, one could argue that data memory should be larger than program memory, as all programs are probably smaller than e.g. 4GiB, but might deal with much larger amounts of data. Therefore, one could devise an ABI for e.g. AMD64 or AArch64 with 32bit `void (*)()` but 64bit `void*` - like an inverse x32 ABI. This would defeat ASLR somewhat, though. – Erlkoenig Feb 15 '20 at 10:18