Skip to content

Commit db75908

Browse files
PatrickHaeckerararslanLilithHafner
authored
Support field name in fieldoffset (#58100)
`fieldtype` accepts both the field's name or the field's index. It's inconsistent that `fieldoffset` only accepts the field's index, but not its name. This commit adds support to `fieldoffset` for the field's name, documents and tests it. --------- Co-authored-by: Alex Arslan <[email protected]> Co-authored-by: Lilith Orion Hafner <[email protected]>
1 parent 0cdbbf7 commit db75908

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ New library functions
2929
New library features
3030
--------------------
3131

32+
* `fieldoffset` now also accepts the field name as a symbol as `fieldtype` already did ([#58100]).
3233
* `sort(keys(::Dict))` and `sort(values(::Dict))` now automatically collect, they previously threw ([#56978]).
3334
* `Base.AbstractOneTo` is added as a supertype of one-based axes, with `Base.OneTo` as its subtype ([#56902]).
3435

base/runtime_internals.jl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,10 +1007,25 @@ morespecific(@nospecialize(a), @nospecialize(b)) = (@_total_meta; ccall(:jl_type
10071007
morespecific(a::Method, b::Method) = ccall(:jl_method_morespecific, Cint, (Any, Any), a, b) != 0
10081008

10091009
"""
1010-
fieldoffset(type, i)
1010+
fieldoffset(type, name::Symbol | i::Integer)
10111011
1012-
The byte offset of field `i` of a type relative to the data start. For example, we could
1013-
use it in the following manner to summarize information about a struct:
1012+
The byte offset of a field (specified by name or index) of a type relative to its start.
1013+
1014+
# Examples
1015+
```jldoctest
1016+
julia> struct Foo
1017+
x::Int64
1018+
y::String
1019+
end
1020+
1021+
julia> fieldoffset(Foo, 2)
1022+
0x0000000000000008
1023+
1024+
julia> fieldoffset(Foo, :x)
1025+
0x0000000000000000
1026+
```
1027+
1028+
We can use it to summarize information about a struct:
10141029
10151030
```jldoctest
10161031
julia> structinfo(T) = [(fieldoffset(T,i), fieldname(T,i), fieldtype(T,i)) for i = 1:fieldcount(T)];
@@ -1032,8 +1047,12 @@ julia> structinfo(Base.Filesystem.StatStruct)
10321047
(0x0000000000000060, :ctime, Float64)
10331048
(0x0000000000000068, :ioerrno, Int32)
10341049
```
1050+
1051+
!!! compat "Julia 1.13"
1052+
Specifying the field by name rather than index requires Julia 1.13 or later.
10351053
"""
10361054
fieldoffset(x::DataType, idx::Integer) = (@_foldable_meta; ccall(:jl_get_field_offset, Csize_t, (Any, Cint), x, idx))
1055+
fieldoffset(x::DataType, name::Symbol) = fieldoffset(x, fieldindex(x, name))
10371056

10381057
"""
10391058
fieldtype(T, name::Symbol | index::Int)

test/reflection.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ tlayout = TLayout(5,7,11)
346346
@test !hasproperty(tlayout, :p)
347347
@test [(fieldoffset(TLayout,i), fieldname(TLayout,i), fieldtype(TLayout,i)) for i = 1:fieldcount(TLayout)] ==
348348
[(0, :x, Int8), (2, :y, Int16), (4, :z, Int32)]
349+
@test [fieldoffset(TLayout, s) for s = (:x, :y, :z)] == [0, 2, 4]
349350
@test fieldnames(Complex) === (:re, :im)
350351
@test_throws BoundsError fieldtype(TLayout, 0)
351352
@test_throws ArgumentError fieldname(TLayout, 0)

0 commit comments

Comments
 (0)