2

I found similar question Compile-time generic type size check, but it not received any answer.

The problem is in cooperation with other programming language via FFI + unsafe, I want to be sure that mem::size_of::<*mut T>() have suitable size. I found such static_assert macro 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);

it works, but if I use mem::size_of::<*const f64>() inside macro all fails, because of: calls in constants are limited to struct and enum constructors, any idea how to calculate size_of *const f64 at compile time?

Community
  • 1
  • 1
fghj
  • 8,898
  • 4
  • 28
  • 56
  • 2
    opening a duplicate is not the way to go if another question did not receive an answer, if you want to increase the visibility of the other question, consider adding a [bounty](http://stackoverflow.com/help/bounty) to it – oli_obk Aug 18 '16 at 16:31
  • 2
    It does not look a complete duplicate to me, could you expand how this question is different from [this related question](http://stackoverflow.com/questions/30330519/compile-time-generic-type-size-check) you linked? – Matthieu M. Aug 18 '16 at 19:09
  • 2
    `mem::size_of` is not yet evaluable at compile time. Wait a year and the story might change (but maybe not, who knows?). – Veedrac Aug 19 '16 at 01:49

1 Answers1

3

For pointers there is a configuration flag that you can check. You could do this to force a compile-time error:

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

In general there is the "transmute trick": to assert the size of something at compile-time, transmute it to something which is known to have the correct size in a dead function. For instance:

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

These tricks will have to do until size_of is made into a const fn.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
durka42
  • 1,502
  • 10
  • 17
  • Thanks. Can you explain what type mean exclamation mark here ` -> !` ? – fghj Aug 19 '16 at 21:30
  • 1
    It means it is a [diverging function](https://doc.rust-lang.org/reference.html#diverging-functions). – antoyo Aug 19 '16 at 22:30
  • For the record, I've removed the `-> !` that @user1034749 asked about, due to [a compiler bug](https://github.com/rust-lang/rust/issues/35849). – durka42 Aug 22 '16 at 18:11
  • @durka42 for the note I create this bug report :) – fghj Aug 22 '16 at 19:44