Question

I have a question about the pointers representation in C. If I have correctly understand this paragraph of the C11 standard :

C11 (N1570), § 6.2.5.28, Types, p. 36

Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements.

I deduced that the types int * and int const * have the same representation but not the types int ** and int const **. Am I right ?

If so, I want to know why the two types don't have the same representation in the second case ? I mean, int and int const have the same representation, idem for int * and int const *, so what's the matter with int ** and int const ** ?

Was it helpful?

Solution

As Bart van Ingen Schenau also stated I think that the standardization committee wanted to put as few restrictions on the representation of pointers as possible. From a compiler point of view it would be useful to have a distinct representation for int * and int const *, because constants could be placed in a bigger or smaller memory and consequently smaller pointers could be used to point into the smaller memories. This would however have meant that the %s format specifier of printf should come in two versions, one for a constant string and one for a non-constant string. This would break a lot of legacy code and my guess is that the standardization committee lacked the courage to enforce that onto the community. And probably rightfully so. As there are no compelling reasons to enforce the same representation for int ** and int const **, they left it that way. Using a different representation for these pointer is however hardly ever useful, except maybe for some corner case applications.

They might also have decided that only char * and char const * should have the same representation, just to save %s, but maybe there are some other interfaces that require equality for pointers to other primitive types as well.

Similarly it would on some systems be desirable to have a different pointer representation for something in global memory, something on the stack and something in the heap. It is however possible in C to use a pointer in such a way that it may contain either such pointer (again you could think of varargs) and it is thus required to at least have a pointer representation that can represent all of them.

In the Embedded-C extension on C memory space have been introduced to explicitly allow the programmer to get data from different data-buses without the need for a pointer type that can represent them all. Such memory spaces could also be used to specify dedicated memories for constants, heap etc. Thus allowing more efficient pointer representations.

A colleague of mine also mentioned that K&R prototypes, or better the absence thereof, are still allowed. In such cases the compiler can not detect the difference in representation between a parameter declaration and use. This would undoubtedly lead to many undetected problems in legacy software. These issues could have been resolved by requiring the use of a common representation on parameter passing (including varargs) as for example is done for float to double in varags, but that would also compromise the intended efficiency of a different representation.

OTHER TIPS

You are correct that int * and int const * are required to use the same representation and int ** and int const ** do not have that requirement.

The reason for not requiring the same representation is most likely to avoid putting unneeded restrictions on C compilers for weird architectures and at the same time making the specifications for C not harder to understand than needed.

Note that there are implementations where, for example, char* and int* have a different size. This probably led to the basic assumption that pointers to different types can have different representations and then exceptions to that basic rule were made for pointers to compatible types and pointers to structures/unions.

To my knowledge, there are no implementations that take advantage of this leeway for int ** and int const **, except perhaps the compiler for the DS9K.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top