Reference arithmetic C works strangely. I conducted two simple experiments and it turned out that they are not calculated:

a = b->c->c->... a = &((*b)->c); 

Declarations of the same type name as struct T and T are different types and cause a conflict. Is this how it should be, or is my compiler defective?

gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010

 #define NULL ((void*)0) typedef struct Ts * Tp; typedef struct { struct Tp c; } Ts; Ts c = {NULL}; /*1-!*/ Ts b = {&c}; /*2-!*/ Ts a = {&b}; /*3-!*/ Tp d = &a; /*4-!*/ int main(void) { Tp e = d->c->c->c; /*5-?*/ Tp * f = &d; /*6-!*/ f = &((*f)->c); /*7-?*/ f = &a.c; /*8-!*/ *f = (*f)->c; /*9-?*/ return 0; } 

And without a pointer declaration - even worse:

 #define NULL ((void*)0) typedef struct { struct T * c; } T; T c = {NULL}; /*1-!*/ T b = {&c}; /*2-?*/ T a = {&b}; /*3-?*/ T * d = &a; /*4-!*/ int main(void) { T * e = d->c->c->c; /*5-?*/ T ** f = &d; /*6-!*/ f = &((*f)->c); /*7-?*/ f = &a.c; /*8-?*/ *f = (*f)->c; /*9-?*/ return 0; } 

A question mark is marked with lines with errors or warnings. Thank you in advance.

  • Address arithmetic in C works correctly. What is your question? - Yaroslav
  • Well, in the first variant, the struct Ts is not declared at all. Perhaps you wanted to write - `typedef struct Ts * Tp; typedef struct Ts {Tp c; } Ts; `? Only from such typedef code will not become clearer. - avp
  • And what do you want to program? - avp
  • I worked with C not much. How correctly to declare the recurrent link in structure, without superfluous naming? If the type has a structure, why do you need to write this struct everywhere? - Vyacheslav

4 answers 4

Do not want to replace

 typedef struct { struct T * c; } T; 

on

 typedef struct U { struct U * c; } T; 

?

  • 2
    Of course, I do not advise doing this, but writing a typedef struct T * T; struct T { struct T * T; }; .... TT = {0}; .. T->T typedef struct T * T; struct T { struct T * T; }; .... TT = {0}; .. T->T typedef struct T * T; struct T { struct T * T; }; .... TT = {0}; .. T->T correct - Yaroslav
  • Declaring a typedef struct S {struct S * c; } T; The second example has earned, all but the fifth expression. But this is not logical, but what kind of structure is S or T? Why is this a lot of words? - Vyacheslav
  • one
    @ Vyacheslav: This structure has type struct S You still have a short nickname for this type of T Why - you need to ask. Would make a typedef struct S { struct S * c; } S; typedef struct S { struct S * c; } S; and would use on health the short name of S . Why was to invent a new name T ? - AnT
  • The duality of the structure type declaration is only in C. T is not an alias, but the name of the type is for some reason incompatible with S. When applying T to variables, it is not necessary to specify the struct in the program, unlike S. You are right, the extra characters are harmful. - Vyacheslav

Declarations of the same type name as struct T and T are different types and cause a conflict.

Of course. It has always been in the language of C.

Your placement of question marks is also in doubt. In the first example, the declaration of the field struct Tp c; - already an error, because the type of struct Tp in the program is not defined, and declaring fields of incomplete types in the C language is prohibited. Then you can not look, and why you put some question marks in this code is not clear.

In the second example, there are common types of type mismatch between a non-defined struct type with a typedef-alias T and no relation to it that does not have an undefined tag type struct T

  • In a real compiler, the declaration of the type of the structure as typedef struct T {struct T * t; ...} T; typedef struct T {struct T * t; ...} T; resolved all problems with type incompatibility and recurrence. In the first example, a struct declaration before Tp c; erroneous, you are right. - Vyacheslav

I think I understood the question. You want to use a structure override when initializing a structure. Your record

 typedef struct T { struct TT; } T; 

Equivalent recording

 struct T { struct TT; }; typedef strcut TT; 

But the redefinition can be before the declaration of the structure, so you can write it like this

 typedef struct TT; struct T { T * T; }; 

But I am making this design like this

 typedef struct _name_s name_s; struct _name_s { name_s * name; }; 
  • Yes, you are right, this confusion with structures and types is characteristic only for C. It happened so that the structures were in C before the introduction of the type system and typedef . - Vyacheslav

It is possible to declare a recurrent reference in the structure as follows:

 typedef struct T { struct T * c; } T; 

Verbose, but this is how it works. Thank you, Yaroslav.

  • one
    Well, not necessarily do it that way. Alternative version of the same: typedef struct TT; struct T { T *c; }; typedef struct TT; struct T { T *c; }; . Verbosity is no different, but in some cases it can be better. - AnT