9

I have a newtype wrapper around an array. I assumed that I could use size_of instead of manually passing the size of the array around, but the compiler thinks I'm wrong.

use std::mem::{size_of, size_of_val};

#[repr(C, packed)]
struct BluetoothAddress([u8, ..6]);

fn main() {
    const SIZE: uint = size_of::<BluetoothAddress>();

    let bytes = [0u8, ..SIZE];
    println!("{} bytes", size_of_val(&bytes));
}

(playpen link)

I'm using the nightly: rustc 0.13.0-nightly (7e43f419c 2014-11-15 13:22:24 +0000)

This code fails with the following error:

broken.rs:9:25: 9:29 error: expected constant integer for repeat count, found variable
broken.rs:9     let bytes = [0u8, ..SIZE];
                                    ^~~~
error: aborting due to previous error

The Rust Reference on Array Expressions makes me think that this should work:

In the [expr ',' ".." expr] form, the expression after the ".." must be a constant expression that can be evaluated at compile time, such as a literal or a static item.

0

1 Answer 1

6

Your SIZE definition is not legal; it’s just that the errors in it occur later than the error on the array construction. If you change [0u8, ..SIZE] to [0u8, ..6] just so that that part works, you find the problems with the SIZE declaration:

<anon>:7:24: 7:53 error: function calls in constants are limited to struct and enum constructors [E0015]
<anon>:7     const SIZE: uint = size_of::<BluetoothAddress>();
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:7:24: 7:51 error: paths in constants may only refer to items without type parameters [E0013]
<anon>:7     const SIZE: uint = size_of::<BluetoothAddress>();
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~

You simply can’t call size_of like that at present.

An alternative is to invert things so that SIZE is the canonical definition and the other places use it:

use std::mem::{size_of, size_of_val};

const SIZE: uint = 6;

#[repr(C, packed)]
struct BluetoothAddress([u8, ..SIZE]);

fn main() {
    let bytes = [0u8, ..SIZE];
    println!("{} bytes", size_of_val(&bytes));
}

Update: With Rust 1.0, this question has been effectively obsoleted, and the compiler error messages have been improved so that they are even more clear.

Furthermore, with #42859 recently landed, rustc nightly will allow using size_of in a constant context, provided the crate has #![feature(const_fn)] (and when #43017 lands, that won’t be needed any more either, and then it will filter through to stable).

In other words, improvements to the language have made this no longer an issue.

Sign up to request clarification or add additional context in comments.

4 Comments

Is there an RFC or GitHub issue for a sizeof construct that works at compile time?
@rraval: there is a desire for Compile-Time Function Evaluation in general, however that is not something for 1.0 which is the focus for now. While size_of could be special-cased, it might just not be worth it.
There is a limited RFC for it here, but it's pretty bare: github.com/rust-lang/rfcs/issues/322
Chris, I saw your flag and everything you said made sense to me, except that we don't generally just delete questions because they have become obsolete. Not everyone is able to update to the latest version of the compiler, so having Q&A about older versions may still be useful. However, to stave off potential confusion, I tried to edit an update into your answer, borrowing from your flag and comments. I probably did a bad job, though, because I don't know Rust. Feel free to tweak it however you see fit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.