Pull to refresh
3
0

Разработчик

Send message

Сработает, как написал mayorovp. Но более каноничным будет сделать такой базовый контейнер на unsafe и голых указателях, верифицировать все unsafe места и предоставить safe интерфейс.

Предлагается считать функцию Box безопасной, но гарантий, в данном случае, нет. Целиком полагаемся на разработчика. Мало ли что он там поместил внутрь, на то и служат маркеры version=nightly/unsafe чтобы не доверять, а проверять.

Гм, а как вы в таком случае доверяете функциям выделения памяти в других языках? Там ведь тоже приходится, о ужас, полагаться на разработчика рантайма, разработчика SDK операционной системы… Мало ли что они там внутри понаписывали.


Если серьёзно, box — такой себе интринсик, завёрнутый в нормальную функцию.

Судя по новостям, closed-source частенько не работает даже после прямых пенделей, вплоть до судебного преследования написавших патч энтузиастов.

Поправьте меня, но из статьи следует, что "не смогла" в данном случае - застряла в бюрократии и разбирательствах по тендеру.

Так вопрос был не к вам, а к QeqReh, который говорит, что с ошибками в Go просто работать. Чего я пока что не наблюдаю.

Вопрос был про Go:


У Григория явно мало опыта в Go

Про ситуацию в Rust я в курсе, спасибо.

Насколько я понимаю, проблемы boilerplate кода вида


..., err := do_something()
if err != nil {
    return ..., err
}

а также случайного игнорирования тех самых err он не решает никак.
Поправьте пожалуйста если ошибаюсь.

И что значит незначительная просадка? Это почти удвоение

По сравнению с затратами на саму аллокацию. Плюс вы сами привели примеры, что компилятор вполне способен "прожевать" не слишком сложные случаи и выполнить RVO.

Сейчас же стандартная библиотека Rust генерирует код аллокации принципиально неоптимизируемый, ради чего?

Как вы сами показали, компилятор вполне способен такое оптимизировать.


Просто разработчики не учли кейс изначально

Насколько мне известно, оператор box в каких-то вариантах существует с незапамятных времён. В целом, дискуссия по placement box активно велась ЕМНИП года два или три назад.


или очень боялись передрать паттерн из плюсов

Дело скорее в отсутствии концепции конструктора. В таком случае любой случай allocate then init становится unsafe.


Последнее, что нашлось — Placement by return, эксплуатирующий (Named) Return Value Optimization и Guaranteed Copy Elision. С моей точки зрения, это более элегантный подход, не требующий специального синтаксиса. Единственная проблема — RFC висит уже больше года. Но обсуждение идёт, последний комментарий был 25 дней назад.

У меня чем дальше, тем чаще возникает вопрос. А так ли уж важно иметь явную inplace инициализацию везде? В большей части прикладного кода в общем-то по барабану, будет там лишний memcpy на пару сотен байт или нет. RVO в релизе прекрасно работает и покрывает 95% случаев. Ну а если прям вот совсем нужен inplace init, можно в отдельных местах unsafe.
Ещё следует учесть, что поддержку оператора box нужно будет делать не только для типа Box, но везде, где происходит выделение не на стеке.

Значит несущественная. Я и написал, что могу ошибаться.

В новостях упоминали, что без него просадка может быть процентов 10. Но тут могу и ошибаться.
Гораздо важнее КМК то, что интел гоняли на DDR5, а амд — на DDR4. Вообще, конечно, вендоры чего угодно любят подобные "честные" тесты в свою пользу.

Value categories

Там вполне чётко написано, что lvalue может находиться слева от оператора присваивания, а rvalue - справа.

Хотя эту ссылку вы должны были найти раз добрались до BCPL.

  1. Любая синтаксически корректоная программа, написанная пусть даже и 20 лет назад обязана компилироваться.

При этом от эпох комитет пренебрежительно отмахивается.


Swift (у Apple)

ЕМНИП там везде принудительный подсчёт ссылок. Любой системщик мгновенно поднимет на вилы. Плюс за пределами экосистемы эппла распространение стремится к нулю.

Для плюсов альтернатива нужна не только в языке, но скорее в нормальном менеджере пакетов, например, и прозрачной системе сборки.

ИМХО этого не произойдёт никогда. Слишком много разных систем сборки и пакетных менеджеров с разными идеологией и подходами к решению тех или иных проблем. Комитет, даже если бы захотел какой-то унификации, мгновенно потонул бы в перетягивании одеяла в десятке разных направлений.

И сколько денег и ватт потребляет система охлаждения.
А то может оказаться, что ценник доступен в основном интеловской лаборатории.

Фраза "укушенный Александреску" существует не зря :)

Я вот нихера не понимаю, почему где-то нужно std::move(x) и без указания типа x. А где-то нужно std::forward<A>(x). Пришлось просто заучить.

В обоих случаях необходимость функций-прокладок вызвана тем, что любое именованное значение будет восприниматься как lvalue. Даже если x — rvalue reference. Подозреваю, это тяжёлое наследие С. Чего не происходит с результатом функции. Поэтому, кстати, есть отдельно auto a = foo() и decltype(auto) a = foo(). При этом std::move всегда превращает аргумент в rvalue reference, поэтому ему не требуется подсовывать тип под нос явно. А вот с std::forward интересней. Он используется в основном при perfect forwarding и должен вернуть аргумент ровно того типа, которого он был. Однако из-за особенностей системы типов, в т.ч. "сжатия ссылок" (A & && -> A &) и толкования всего именованного как lvalue, мы опять же теряем часть информации о типе при передаче его куда-либо. Чтобы воспользоваться магией функции-прокладки, мы должны откуда-то подсунуть ей тип. Именно поэтому пишется именно std::forward<A>(a). A берётся из типов-параметров. Подозреваю, можно было бы писать std::forward>decltype(a)>(a), но первый вариант банально короче.

Это нужно в том случае, когда вы не знаете реальный тип a,

Не совсем верно. Это нужно потому, что любое именованное значение автоматом передаётся как lvalue, даже если это rvalue reference. А вот результат функции ни к чему не приводится. Таким образом, применение функции-прокладки std::forward позволяет обойти это ограничение системы типов.

1
23 ...

Information

Rating
Does not participate
Location
Украина
Registered
Activity