2016-08-18 6 views
2

Ich fand ähnliche Frage Compile-time generic type size check, aber es erhielt keine Antwort.Überprüfen Sie Zeigergröße zur Kompilierzeit

Das Problem ist, in Zusammenarbeit mit anderen Programmiersprache über FFI + unsicher, ich sicher sein will, dass mem::size_of::<*mut T>() geeignete Größe haben. Ich fand solche static_assert Makro in Internet:

macro_rules! static_assert { 
    (type $t:ty;) => (
     type __StaticAssert = $t; 
    ); 

    (type $t:ty; $e:expr $(, $ee:expr)*) => (
     static_assert!(type ($t, [i8; 0 - ((false == ($e)) as usize)]); $($ee),*); 
    ); 

    ($e:expr $(, $ee:expr)*) => (
     static_assert!(type [i8; 0 - ((false == ($e)) as usize)]; $($ee),*); 
    ); 
} 

static_assert!(2 == 2); 

es funktioniert, aber wenn ich mem::size_of::<*const f64>() innen Makro verwenden, um alle fehlschlägt, wegen: calls in constants are limited to struct and enum constructors, eine Ahnung, wie size_of*const f64 bei der Kompilierung zu berechnen?

+2

Das Öffnen eines Duplikats ist nicht der richtige Weg, wenn eine andere Frage keine Antwort erhalten hat. Wenn Sie die Sichtbarkeit der anderen Frage erhöhen möchten, sollten Sie eine [Kopfgeld] hinzufügen (http://stackoverflow.com/help/). Bounty) –

+2

Es sieht nicht ein komplettes Duplikat für mich, könnten Sie erweitern, wie diese Frage anders ist als [diese verwandte Frage] (http://stackoverflow.com/questions/30330519/compile-time-generic-type- Größenprüfung) Sie verlinkt? –

+2

'mem :: size_of' ist zur Kompilierzeit noch nicht auswertbar. Warten Sie ein Jahr und die Geschichte könnte sich ändern (aber vielleicht nicht, wer weiß?). – Veedrac

Antwort

2

Für Zeiger gibt es ein Konfigurationsflag, das Sie überprüfen können. Sie können dies tun, um einen Fehler bei der Kompilierung zu erzwingen:

#[cfg(not(target_pointer_width = "64"))] 
const ERROR:() = "Your pointers are too small. Please try again with a more expensive computer."; 

Im Allgemeinen gibt es die „verwandelt Trick“: die Größe von etwas zur Compile-Zeit zu behaupten, verwandelt es zu etwas, das die dafür bekannt ist, korrekte Größe in einer toten Funktion. Zum Beispiel:

#[allow(dead_code)] 
fn _assert_pointers_are_64bits() { 
    unsafe { 
     ::std::mem::transmute::<*const f64, [u8; 8]>(panic!()); 
    } 
} 

werden diese Tricks zu tun, bis size_of in eine const fn gemacht wird.

+0

Danke. Kannst du erklären, was für ein Ausrufezeichen hier steht? '->!'? – fghj

+1

Es bedeutet, dass es sich um eine divergierende Funktion handelt (https://doc.rust-lang.org/reference.html#diverging-functions). – antoyo

+0

Für die Aufzeichnung, habe ich die '->!' That @ user1034749 gefragt, wegen [einem Compiler-Fehler] (https://github.com/rust-lang/rust/issues/35849) entfernt. – durka42

Verwandte Themen