Byte size of a type in a macro (i.e. can't call `sizeof` in a macro)

Hi there, I recently starting using Crystal and I am loving it so far.

I have one issue that I can’t solve at the moment: is it possible to get the byte size of a type within a macro? When I call, e.g. sizeof(Int32) it tells me I can’t do this.

Here’s a simplified version of what I am trying to do:

class Example
  macro fields(*fs)
     {% offset = 0 %}
     {% for f in fs %}
     def {{f.var}}
        # calculate value for field based on offset
     end
    {% offset += sizeof(Int32) %} # I want this to be f.type but that doesn't work
    {% end %}
  end
end

class SubExample < Example
   fields(foo : Int32)
end

When I run this I get:

Error: can't execute SizeOf in a macro

Is there an alternative method I can use?

Many thanks for your help!

Sorry for the late reply, I just noticed this comment was still sitting as draft

I don’t think the exact byte size of types is available at the semantic stage when macros evaluate.
sizeof expressions are only resolved in codegen.

Could you explain a bit what you want to do with this?

I’m thinking maybe we should allow sizeof and alignof inside macro expressions when the argument is a primitive non-struct Value type, whose size should be constant for any given target and defined by the compiler.

2 Likes

Same goes for certain uses of sizeof as generic type arguments, e.g. Allow integer expressions and sizeof() as part of type notation · Issue #5427 · crystal-lang/crystal · GitHub