Hello guys,
I was wondering how to retrieve the size of a type declared as a
ref object
Consider this example:
type
MyObject = object
a : int
b : int
c : int
MyRefObject = ref object
a : int
b : int
c : int
echo sizeof(MyObject) #Correctly outputs 24
echo sizeof(MyRefObject) #Outputs only the size of the pointer, 8
How could I retrieve the size of the underlying structure of
MyRefObject
?with []
echo sizeof(MyObject()) #Correctly outputs 24
echo sizeof(MyRefObject()[]) #Outputs 24
MyRefObject()[]
allocating an unitialized instance of the type? Isn't there a way to achieve the same thing without creating an object of the type?You can wrap the sizeof in static(sizeof(MyRefObject()[])) but I'm pretty sure the VM will complain that there is no address at compile-time.
Alternatively from the following definition
type
MyObject = object
a : int
b : int
c : int
MyRefObject = ref MyObject
You can make sure that MyRefObject is always up-to-date with MyObject implementation for your sizeof.
If you want one step further, you can implement a typed macro with getType and getImpl that resolve the ref MyObject from the MyRefObject type, and then statically calls sizeof on that. This is left as an exercise to the reader ;).
This works, but also creates an instance?
proc f[T: ref](): int {.compileTime.} = sizeof(T()[])
You can do what you want at compile time with a macro like so:
import macros
macro msizeof(obj: typedesc): untyped =
let ty = obj.getType()
var sym: NimNode
if ty[1].kind == nnkBracketExpr:
# This is a ref object
sym = ty[1][1]
else:
# This is a normal object
sym = ty[1]
result = quote do:
sizeof(`sym`)
type
MyObject = object
a : int
b : int
c : int
MyRefObject = ref object
a : int
b : int
c : int
echo msizeof(MyObject) # Prints 24
echo msizeof(MyRefObject) # Also prints 24
The original solution should work without allocation. I use a noRef helper for sizeof and =destroy
echo sizeof(block:
echo "no side effect"
MyRefObject()[])
template noRef*(T: typedesc): typedesc =
typeof(default(T)[])
echo sizeof(noRef(MyRefObject))
echo sizeof(MyRefObject[])
should just work, bug report please.
@araq merged a fix into the devel channel.
sizeof(MyRefObject[])
now prints the size of the underlying MyObject.
After updating and switching to the devel channel via choosenim :)