2015-09-06 9 views
5

Ho bisogno di allineare una struttura a un limite di 16 byte in Rust. Sembra possibile dare suggerimenti sull'allineamento completo del repr attribute, ma non supporta questo caso d'uso esatto.Come allineare una struttura a un limite di byte specificato?

Un test funzionale di quello che sto cercando di realizzare è un tipo Foo tale che

assert_eq!(mem::align_of::<Foo>(), 16); 

o, in alternativa, una struttura Bar con un campo baz tale che

println!("{:p}", Bar::new().baz); 

stampa sempre un numero divisibile per 16.

È attualmente possibile in Rust? Ci sono dei work-arounds?

+1

Vuoi dire che vuoi avere una struttura nell'heap con un allineamento specifico? Non sono a conoscenza dell'allineamento per i tipi allocati allo stack, ma l'unstable ['allocate'] (http://doc.rust-lang.org/std/rt/heap/fn.allocate.html) ha un allineamento discussione. – Shepmaster

+1

Inoltre, si parla dell'imballaggio come allineamento decrescente; intendi dire che devi avere un * membro * di una struttura sempre ad un allineamento specifico? Potresti voler rafforzare la tua domanda con qualche codice di esempio, diagrammi di memoria ASCII-art o più prosa che descrivono il motivo per cui devi farlo in modo che tutte le persone siano più intelligenti di quanto io possa aiutarti.^_^ – Shepmaster

+0

Grazie per il feedback, @Shepmaster! Intendevo allineato in generale, ma sì, il mio caso d'uso specifico è per lo stack. Aggiornerò la mia domanda per essere più chiara. –

risposta

10

Non c'è modo di specificare l'allineamento direttamente al momento, ma è decisamente desiderabile e utile. È coperto da issue #33626 e dal suo RFC issue.

Una corrente work-around per forzare l'allineamento di alcuni struct Foo essere grande come l'allineamento di un certo tipo T è quello di includere un campo di tipo [T; 0] avente dimensioni pari a zero e quindi non altrimenti influenzare il comportamento del struct, ad es struct Foo { data: A, more_data: B, _align: [T; 0] }.

Su notte, questo può essere combinato con tipi SIMD per ottenere uno specifico allineamento elevato, poiché hanno un allineamento uguale alla loro dimensione (beh, la potenza successiva di due), ad es.

#[repr(simd)] 
struct SixteenBytes(u64, u64); 

struct Foo { 
    data: A, 
    more_data: B, 
    _align: [SixteenBytes; 0] 
} 
+0

Il campo può essere allineato staticamente solo se l'inizio della struttura ha un allineamento noto, perché ha sempre un offset fisso dall'inizio. Quindi, questo trucco funziona in realtà, indipendentemente da dove il campo si trova nell'ordine della struttura. – huon

+0

Non lo sapevo, grazie. Quindi, invece di richiedere '(& struct + offset)% desired_alignment == 0', il compilatore assicura' & struct% desired_alignment == 0 && offset% desired_alignment == 0? Ciò sembra terribilmente dispendioso, ma sono sicuro che ci deve essere una ragione - puoi indicarmi qualsiasi risorsa su questo per saperne di più? – U007D