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.

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