According to both C99 §6.2.5p27
and C11 §6.2.5p28
:
All pointers to structure types shall have the same representation and alignment requirements to each other.
With a footnote (#39
and #48
respectively):
The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
(Note that C89 §3.1.2.5
doesn't specify about pointers to structs)
-
It is known that a pointer to void for example, C11 §6.3.2.3p1
:
A pointer to void may be converted to or from a pointer to any object type.
Does not imply that a pointer to pointer to void is the same as a pointer to void, and does not imply the same as other pointers to pointers to data objects.
(I apologize if I use the term 'imply the same' too loosely, it is meant to be used only within the specified context)
The following is a code sample demonstrating a generic pointer to pointer to struct:
#include <stdio.h>
#include <stdlib.h>
int allocate_struct(void *p, size_t s) {
struct generic { char placeholder; };
if ( ( *(struct generic **) p = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("p: %p;\n", (void *) *(struct generic **) p);
return 0;
}
int main(void) {
struct s1 { unsigned int i; } *s1;
if (allocate_struct(&s1, sizeof *s1) != 0)
return -1;
printf("s1: %p;\n\n", (void *) s1);
s1->i = 1;
free(s1);
return 0;
}
GCC:
-std=c89 -pedantic-errors -Wall -Wextra -fstrict-aliasing -Wstrict-aliasing=3 -O3
Result: (without warnings)
p: 0x800103a8;
s1: 0x800103a8;
.
The Question
Whether the implied interchangeability of pointers to structs applies to pointers to pointers of structs just as well?
Just to clarify: the question is about struct x **
vs other struct y **
, and not about struct x *
vs struct y **
.
malloc
ed memory asstruct generic *
, you shouldn't access it asstruct something_else *
. – Exceptionstruct x **
could have different rep fromstruct y **
but the compiler would still be conforming – Lakia...and does not imply the same as other pointers to pointers to data objects.
? – Bobettebobinastruct X; struct Y; struct S { struct X **ptr; };
, we must know aboutstruct X **
before seeing the definition ofstruct X
. Therefore the decision about rep/alignment can only be based on the labelX
(e.g.: lets say if there's a even number of letters inX
thensizeof(struct X**)
is 5, else it's 4). Maybe this is actually possible on second thoughts; I was thinking you could then definestruct X
andstruct Y
to be the same and put them in a union (meaning they must also have the same layout) but that doesn't make any difference – Lakia