How to convert a tuple of references to a reference of a tuple?

后端 未结 1 1787
天命终不由人
天命终不由人 2020-12-21 15:44

I\'d like to convert a tuple of references (which are all references to members of the same struct) to a reference of a tuple.

I\'ve tried to coerce them in various

相关标签:
1条回答
  • 2020-12-21 16:18

    This is impossible.

    A reference refers to a value. You wish to have a &(Bar, Bar) but there is nowhere in memory that has a 2-tuple of (Bar, Bar). You cannot refer to something that does not exist.

    The memory layouts of &(A, B) and (&A, &B) are fundamentally incompatible, so you cannot use unsafe Rust techniques either.


    In this particular case, you might be able to use unsafe Rust to convert your &Foo directly to a &(Bar, Bar), but...

    • it requires that the layout of a tuple struct and a tuple be the same; I don't know that's guaranteed1
    • it requires that the layout of a tuple struct be tightly packed such that you can offset by the member size to get to the next one; I don't know that's guaranteed1
    • it requires that the layout of the tuple struct places the members in the same order they are defined; I don't know that's guaranteed1
    • you can only do it for sequential pieces; no getting the first and third item
    // I copied this unsafe block from Stack Overflow
    // without properly documenting why I think this code is safe.
    let b: &(Bar, Bar) = unsafe { &*(a as *const Foo as *const (Bar, Bar)) };
    println!("{:?}", b);
    
    // I copied this unsafe block from Stack Overflow
    // without properly documenting why I think this code is safe.
    let c: &(Bar, Bar) = unsafe {
        let p = a as *const Foo as *const Bar;
        let p = p.offset(1);
        &*(p as *const (Bar, Bar))
    };
    println!("{:?}", c);
    

    1 — In fact, the reference explicitly states:

    Tuples do not have any guarantees about their layout.

    The exception to this is the unit tuple (()) which is guaranteed as a zero-sized type to have a size of 0 and an alignment of 1.

    This means that while this code may print out what you expect and Miri does not complain, it's undefined behavior.

    0 讨论(0)
提交回复
热议问题