Hi Samuel,

Basically, because all pointers are the same size regardless of their type,
so varying the type of a pointer does not change the overall layout of the
containing struct.

If the field can actually change sizes for different generic types, then it
could affect the size and position of other fields around it. For example,
imagine this:

    struct Foo(T) {
      a @0 :Int16;
      b @1 :Int32;
      c @2 :T;
      d @3 :Int64;
    }

If we replace `T` with the type `Int16`, then the struct will be laid out
like this:

    0...16 a
    16...32 c
    32...64 b
    64...128 d

But if we replace `T` with type `Int32`, then the struct looks like this:

    0...16 a
    16...32 (empty padding)
    32...64 b
    64...96 c
    96...128 (empty padding)
    128...192 d

Notice that the offset to field `d` differs between these. Also notice that
deciding the offset of d depends on the specific details of all the fields
that come before it.

Because of this complexity, if we wanted Cap'n Proto generics to support
varying primitive types, we'd essentially be forced to output a whole copy
of the class for each combination of type parameters, because potentially
all the offsets could differ for each permutation.

*Or* we would need to say that generic types are laid out differently from
the equivalent substituted type.

Either of these options seemed unreasonably bad in practice. So the only
other option was to support varying pointer types only.

Note that this rule doesn't apply to List(T) because List(T) is a built-in
type, not a generic.

-Kenton

On Thu, Apr 30, 2020 at 5:04 PM Samuel Ainsworth <skainswo...@gmail.com>
wrote:

> Following the schema introduction (https://capnproto.org/language.html),
> I have something like the following:
>
> struct Map(Key, Value) {
>   entries @0 :List(Entry);
>   struct Entry {
>     key @0 :Key;
>     value @1 :Value;
>   }
> }
>
>
> struct Directory {
>  contents @0 :Map(UInt64, UInt64);
> }
>
>
> But capnproto isn't too happy about this:
>
> src/newworld/filetree.capnp:51:23-29: error: Sorry, only pointer types can
> be used as generic parameters.
>
> I understand what this is saying, but I'm a bit puzzled as to why this
> constraint exists... Why are only pointer types allowed as the
> instantiations of generic parameters?
>
> Thanks,
> Samuel
>
> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to capnproto+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com
> <https://groups.google.com/d/msgid/capnproto/9668d18e-63d3-4643-ac24-a32f11fc8bde%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQnaAZtHUOcKokUdBV8JRZhehPNqZV2C16opmwZSOjz6Zg%40mail.gmail.com.

Reply via email to