-
It seems hard to use c's offsetof directly |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Ok I found the solution: ## local offsetof = expr_macro(function (T, field)
return #[T.value.fields[field].offset]#
## end) But it has downside: you need to use the ugly syntax Use poly function global function offsetof(T: type, field: string <comptime>): integer <inline>
return #[T.value.fields[field.value].offset]#
end problem: not comptime function |
Beta Was this translation helpful? Give feedback.
-
I will show 5 possible ways to achieve that: local MyRecord = @record{
a: uint32,
b: uint32
}
-- First way, poly function using C `offsetof` (known only at runtime, calculated by the C compiler)
local function c_offsetof(T: type, field: string <comptime>): isize <inline>
local off: isize <noinit>
##[[
cinclude '<stddef.h>'
local type, field = T.value, field.value
cemit(function(emitter)
emitter:add_indent_ln('off = offsetof(', type, ', ', field, ');')
end)
]]
return off
end
assert(c_offsetof(MyRecord, 'b') == 4)
-- Second way, poly function (known at runtime, calculated by the Nelua compiler)
global function func_offsetof(T: type, field: string <comptime>): integer <inline>
return #[T.value.fields[field.value].offset]#
end
assert(func_offsetof(MyRecord, 'b') == 4)
-- Third way, macro of offsetof (known at compile-time, calculated by the Nelua compiler)
## function macro_offsetof(T, field) return T.value.fields[field].offset end
assert(#[macro_offsetof(MyRecord, 'b')]# == 4)
-- Forth way, macro offsetof (known at compile-time, calculated by the Nelua compiler)
## exprmacro_offsetof = expr_macro(function (T, field)
return #[T.value.fields[field].offset]#
## end)
assert(#[exprmacro_offsetof]#(MyRecord, 'b') == 4)
-- Fifth way, inline macro (known at compile-time, calculated by the Nelua compiler)
assert(#[MyRecord.value.fields['b'].offset]# == 4) Also be warned that the field |
Beta Was this translation helpful? Give feedback.
I will show 5 possible ways to achieve that: