Crystal: Preserve order of instance variables

Created on 26 Jul 2016  路  9Comments  路  Source: crystal-lang/crystal

Right now mixing instance variable declarations with uninitialized doesn't preserve the expected order:

class Foo
  @x = uninitialized Int32
  @y : Int32

  def initialize
    @y = 0
  end
end

p Foo.new #=> #<Foo:0x101840fd0 @y=0, @x=0>

The above should print first @x and then @y

/cc @BlaXpirit

bug compiler

Most helpful comment

No, the idea was proposed some time ago but it never got implemented. It's not that hard to implement :-)

In any case I think we could re-order fields unless the struct is marked with @[Extern], which means that you need to keep the layout as told for compatibility with other libraries.

All 9 comments

Interesting, so it was about the uninitialized and not the types of the variables. Thank you very much!

Yes, the uninitialized was processed later so it ended up in the end, I don't know why. Now the declarations are all processed together. I think this should be like this, and it will be specially useful once we allow regular crystal structs to be marked as extern, as here we want to preserve the order.

Aren't ivars re-ordered to conserve space with best alignment (internally)? Ed: In _reference_ types.

No, the idea was proposed some time ago but it never got implemented. It's not that hard to implement :-)

In any case I think we could re-order fields unless the struct is marked with @[Extern], which means that you need to keep the layout as told for compatibility with other libraries.

Since Bools shows up as 0 byte, I assumed there was re-ordering and that bools where squeezed into the alignment spaces :-)

The 0 comes from LLVM (LLVM gives you this value when you ask for the size of an i1). I think LLVM packs multiple bools inside a byte. Maybe it should say 0.125 or something like that :-P

Haha, that would've kept my assumptions in check B-)

class C
  @a = StaticArray(UInt8, 5).new(0u8)
  @x : Int32? = nil
end

p C.new  #<C:0x8c70f30 @x=nil, @a=StaticArray[0, 0, 0, 0, 0]>

Yeah, the first case needs a type guess from the constructor and that happens later. I'll try to refactor things a bit so that at least these assignments get processed in the correct order.

Was this page helpful?
0 / 5 - 0 ratings