Skip to content

The upcoming behavior of reinterpret for isbits types is dubious and not explicitly documented #52135

@nsajko

Description

@nsajko

The upcoming behavior of reinterpret for "plain data" types, introduced in #47116, is to reinterpret only the non-padding bytes of an isbits value. This generalizes the functionality compared to the latest release, v1.9, where reintepreting non-primitive isbits types was not allowed. Personally I'd like for this to get reverted, so I'm listing some issues with it, but at the very least consider this as a doc issue.

  1. Why expand the reinterpret API, which is already unsafe and IMO ugly (e.g., the reinterpret-for-isbits and reinterpret-for-arrays could really have been two different functions)?

  2. The behavior depends on the host endianness, and encourages user code whose correctness depends on the host-endianness. While little-endian is currently completely dominant, this expansion of the reinterpret API seems like an unecessary and subtle footgun for the Julia ecosystem, as it becomes a trap when some big-endian architecture becomes relevant again. Encouraging host-endianness-dependent behavior is especially weird given the "correctness bugs" scrutiny that Julia is subject to.

  3. The padding-handling for isbits-reinterpret types is inconsistent with the array-reinterpret behavior. So, this works for a tuple, but fails for an array of such tuples:

julia> reinterpret(Tuple{UInt16,UInt8}, (0x1, 0x0203))
(0x0301, 0x02)

julia> reinterpret(Tuple{UInt16,UInt8}, [(0x1, 0x0203)])
1-element reinterpret(Tuple{UInt16, UInt8}, ::Vector{Tuple{UInt8, UInt16}}):
Error showing value of type Base.ReinterpretArray{Tuple{UInt16, UInt8}, 1, Tuple{UInt8, UInt16}, Vector{Tuple{UInt8, UInt16}}, false}:
ERROR: Padding of type Tuple{UInt16, UInt8} is not compatible with type Tuple{UInt8, UInt16}.
  1. The new behavior is not documented, except implicitly, through a usage example. While Round-trip reintrepretation of all bits types #47116 tried to document the new behavior, the subsequent Merge new reinterpret with essentials.jl reinterpret #50367 then removed that doc string.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions