[rust-dev] static mut and owning pointers

Alex Crichton alex at crichton.co
Tue Jan 28 15:36:28 PST 2014


Our discussion in a recent meeting concluded that statics will not be
allowed to contain types with destructors, and you also won't be able
to move out of static items:

https://github.com/mozilla/rust/issues/10577#issuecomment-32294407

On Tue, Jan 28, 2014 at 3:34 PM, Kevin Ballard <kevin at sb.org> wrote:
> At first glance it seems reasonable to prohibit moving out of a mutable static, but I'm not sure it really makes sense to try and put restrictions on mutable statics when we can't make them safe.
>
> -Kevin
>
> On Jan 28, 2014, at 3:26 PM, Niko Matsakis <niko at alum.mit.edu> wrote:
>
>> Probably this should yield an error -- I tend to think we should only
>> permit moves that we cannot enforce from `*` pointers, just to add an
>> extra barrier.
>>
>>
>> Niko
>>
>> On Tue, Jan 28, 2014 at 12:12:23PM -0800, Kevin Ballard wrote:
>>> Your code is moving the contents of Option<~MyStruct> into the match arm. It just so happens that this seems to be zeroing out the original pointer in memory, and that happens to be the same representation that None does for the type Option<~MyStruct> (since ~ pointers are non-nullable), so the act of moving the value just happens to be transforming it into a None.
>>>
>>> Normally you couldn't do this, but mutable statics are weird (which is why you need the unsafe block to access it).
>>>
>>> When you remove the ~, the lines end up printing the same because MyStruct is implicitly copyable, so your match arm is now copying instead of moving.
>>>
>>> The correct fix here is to use `Some(ref data)` instead of `Some(data)`. This will take a reference to the data instead of moving it, and the static will remain unchanged.
>>>
>>> -Kevin
>>>
>>> On Jan 28, 2014, at 11:48 AM, Alexander Stavonin <a.stavonin at gmail.com> wrote:
>>>
>>>> Hi all! I'm not sure is it an error or "static mut" variables misunderstanding from my side. The source:
>>>>
>>>> struct MyStruct {
>>>>    val: int
>>>> }
>>>>
>>>> static mut global_data: Option<~MyStruct> = None;
>>>>
>>>> fn test_call() {
>>>>    unsafe {
>>>>        match global_data {
>>>>            Some(data) => { println!("We have data {:?}", data);}
>>>>            None => { println!("We don't have data");}
>>>>        }
>>>>    }
>>>> }
>>>>
>>>> fn main() {
>>>>
>>>>    unsafe {
>>>>        global_data = Some(~MyStruct{val: 42});
>>>>    }
>>>>
>>>>    test_call();
>>>>    test_call();
>>>> }
>>>>
>>>> and output:
>>>>
>>>> We have data ~MyStruct{val: 42}
>>>> We don't have data
>>>>
>>>> But if I'm changing global_data from Option<~MyStruct> to Option<MyStruct> output is changed also:
>>>>
>>>> We have data ~MyStruct{val: 42}
>>>> We have data ~MyStruct{val: 42}
>>>>
>>>> Is it normal behaviour and owning pointers cannot be stored in global variables or an error?
>>>> _______________________________________________
>>>> Rust-dev mailing list
>>>> Rust-dev at mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>
>>> _______________________________________________
>>> Rust-dev mailing list
>>> Rust-dev at mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev


More information about the Rust-dev mailing list