TBH I find it rather surprising that the spec does not mention why `type X
X` is *not* allowed.
It's obvious that it can't be, but from what I can tell, the spec doesn't
forbid it.
Otherwise I would've chalked up the validity of `type X *X` for "anything
that's not forbidden, is allowed". A type definition
<https://go.dev/ref/spec#Type_definitions> is

TypeDef = identifier Type .
> Type = TypeName | TypeLit | "(" Type ")" .
> TypeName  = identifier | QualifiedIdent .
> TypeLit   = … | PointerType | … .

PointerType = "*" BaseType .

BaseType    = Type .


So `type X *X` is obviously valid (after taking scope into account
<https://go.dev/ref/spec#Declarations_and_scope>, as Jam mentions). But so
would `type X X` be.

On Thu, Mar 10, 2022 at 2:04 PM Jan Mercl <0xj...@gmail.com> wrote:

> On Thu, Mar 10, 2022 at 1:40 PM 'wagner riffel' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
>
> > I don't think it's mentioned in the specification, my bet is that
> > unless your type requires inifnity amout of memory (eg: `type t struct
> > {t}`) or the type is an interface and break its rules, (eg: `type
> > iface interface{ iface }`) you can use self-reference.
>
> The validity of `type T *T` in Go is based on two things: 1) The
> visibility of the identifier in `type T ...` is specified to start right
> after the identifier, 2) It's possible, in this case, to compute the size
> of type T. So no problem here.
>
> > You're correct, C doesn't allow self reference in type decl, more ...
>
> In `typedef self *self;` the visibility of the second instance of
> identifier `self` starts only after it, ie. preceding the final `;'. So the
> first identifier `self`, the one after `typedef` is undefined and that's
> the real reason it does not work. However:
>
> ----
> jnml@e5-1650:~/tmp$ cat main.c
> typedef int T;
> typedef T T;
>
> int main() {}
> jnml@e5-1650:~/tmp$ gcc -Wall main.c
> jnml@e5-1650:~/tmp$
> ----
>
> This works because typedef is equal to Go type aliases. But the full Go
> thing cannot work:
>
> ----
> jnml@e5-1650:~/tmp$ cat main.c
> typedef int T;
> typedef T *T;
>
> int main() {}
> jnml@e5-1650:~/tmp$ gcc -Wall main.c
> main.c:2:12: error: conflicting types for ‘T’
>     2 | typedef T *T;
>       |            ^
> main.c:1:13: note: previous declaration of ‘T’ was here
>     1 | typedef int T;
>       |
> ----
>
> Here the problem is that we define T to be two different types, the first
> it's an int and the second is a pointer to int.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAA40n-VotEGgVupaJ6S1zRF%3D3hDHDKAz0V5_enaD9EfYfL7t-Q%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAA40n-VotEGgVupaJ6S1zRF%3D3hDHDKAz0V5_enaD9EfYfL7t-Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfFDr%2BJ5Z79%2BTY_-Yjj5cNniPWRH7ccyK0vSyaHsBcayKA%40mail.gmail.com.

Reply via email to