Почему в Rust нельзя выделять память до main как это можно в C++?

Есть такой код на C++:

#include <iostream>

struct Foo {
    int * ptr;
public:
    Foo() {
        ptr = new int;
        std::cout << "Foo constructor" << std::endl;
    }
    ~Foo() {
        delete ptr;
        std::cout << "Foo destructor" << std::endl;
    }
};

auto foo = Foo();

int main() {
    std::cout << "Hello" << std::endl;
    return 0;
}

Он компилируется и исполняется без каких-либо проблем. В нём до вызова main создаётся объект, выделяется память. Но если сделать что-то подобное в Rust, то компилятор не даст этого сделать:

pub static foo: Foo = Foo::new("Hello".to_string());

Ему не нравится функция to_string(), которая выделяет память. Почему Rust так разработан ? Что в этом безопасного(Rust позиционируется как безопасный системный язык программирования)?


Ответы (1 шт):

Автор решения: Pavel Mayorov

Это связано с тем, что статические выражения в Rust являются constexpr в терминах С++, constexpr-выражения тоже запрещают выделение памяти.

Причина тут не столько в безопасности, сколько в принципе "не платить за то, что не используется". Если разрешить произвольные функции при инициализации статических переменных - то одна из них может создать новый поток, который может обратиться к другой статической переменной перед её инициализацией. В итоге понадобится по мьютексу на каждую переменную (и в том же С++ так и делается!), что приедет к куче расходов на многопоточность даже в однопоточных программах.

→ Ссылка