I searched online and while I could find a few discussions, I did not find a comprehensive description. So if anyone could form an answer which covers everything about size
This question was originally tagged C and C++, not “language agnostic”. As a language-agnostic question it should be closed as being too broad, but I’m hoping that the OP will revert it to the original versionl, and so I'm not voting to close. As a C/C++ question, while eminently answerable it was closed as being too broad, and then when the scope was enormously broadened to unanswerable, by changing that tagging to language-agnostic, it was reopened as being now answerable.
I’m answering the original question for C++, with a few bits of C knowledge sprinkled here and there.
I think the current “language-agnostic” question is unanswerable in spite of one attempted language-agnostic answer.
1. What does the size of a pointer depend on?
The minimum required size of an ordinary data pointer depends on the maximum number of possible memory locations of objects of the pointed-to type, or of different functions; to differentiate n possible locations ceil(lg2(n)) bits are needed.
Hence the minimum pointer size depends on maximum possible memory size.
And hence the minimum pointer size also depends on the alignment of the pointed-to type. On some now archaic machines, and possibly even on some extant machines (mainframe?), the hardware level addressable unit of memory was a word of e.g. 2 or 4 bytes. Word aligned data could then be addressed with small pointers, while char*
and hence also void*
needed to be larger.
Consequently, the C++11 standard in §3.9.2/4 requires that “An object of type cv void*
shall have the same
representation and alignment requirements as cv char*
.”
Member function pointers in C++ are more akin to offsets than pointers, and are often larger than proper pointers.
2. What feature of architecture affects the size of a pointer? (In detail)
Mainly the adressable range of memory as seen from C++.
But also it's worth recalling that in MS-DOS programming one differentiated between near and far pointers. A near pointer was an offset into an implied 64K segment of memory, while a far pointer, twice the size, combined a segment selector and offset.
In (still) modern 32-bit PC programming C and C++ pointers are as a rule akin to near pointers, with no support for far pointers, which would be 6 bytes. To use such pointers it's necessary to use other languages such as assembly language.
3. Does the compiler affect the size of a pointer? How?
The compiler and compilation options used can in principle affect the pointer size, because the size is not prescribed by the standard. E.g. it can in principle add information to aid with debugging. Or as mentioned, with language extensions there can be near and far pointers.
Since member pointers are not directly addresses (under the hood), it's very much up to the compiler how to represent them, and how large they are.
This can also depend on the options used.
4. What are the different types of pointers and how are they different from each other? (Eg: Is there a difference between function pointers and a pointer pointing to a basic data type?, near pointer vs far pointer etc)
In C++03 a function pointer could not be converted to a data pointer or vice versa. This restriction supported machines with Harvard architecture, and it supported possible different sizes of function pointers and data pointers (e.g. with the former as far and the latter as near). In C++11 such conversion is conditionally supported, in §5.2.10/8, resulting from Defect Report 195.
It's worth noting that the Posix standard requires support for conversion (function pointer) → (void*
) and back, e.g. for the dlsym
function.
The above effectively means that object pointers and functions pointers are different. E.g. the latter don't support address arithmetic. Also, member pointers are different from proper pointers, and are more akin to offsets.
Modern C++ does not support near versus far pointers.
5. Does the language have any effect on pointer. C vs C++
C doesn't support member pointers, to the degree that they are considered pointers in this question.
Other than that, a main goal of C++ is to be able to use C libraries directly, and the C standard is “incorporated” (C++11 §17.5.1.5/1) into the C++ standard, which requires compatible pointer representations.
C supports restricted pointers, the qualifier restrict
, which C++ doesn't support. However, this only affects the knowledge that the compiler has about the possible values of a pointer. Which means that a C compiler might be able to emit better optimized code.
A pointer is an abstraction provided by a high-level language; in theory it could be any width at all. It's totally at the whim of the compiler.
In practice, it's typically related to the width of the memory addresses of the underlying hardware, as that's usually the most efficient thing for the compiler to implement. There are exceptions though; for example, C++'s pointer-to-member-function does not have a direct mapping to hardware addresses, as it needs to represent two entities (the function and some notion of the type).
However, even leaving that aside, there are still complexities. For example: