Pull to refresh

Comments 16

В реальном коде может возникнуть такое UB?

Пока похоже, что для того, что бы получить это UB нужно специально так написать код. (учитывая, что нужно аргумент функции на placeholder менять)

начать нужно бы было с вопроса:

А есть ли для Rust стандарт?

Потому что UB это то что определено в стандарте.

Пока нет стандарта нет и UB.

Скорее это то, что НЕ определено в стандарте и стандарт не требует документирования.

Таким образом, если пользоваться наивной логикой, весь Раст -UB ( да помилует меня дух Рассела)

Справедливости ради undefined behavior это все таки термин определенный стандартом, также как unspecified behavior, implementation-defined behavior.

3.4.3 1 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

или

Undefined behavior gives the implementor license not to catch certain program errors that are difficult to diagnose. It also identifies areas of possible conforming language extension: the implementor may augment the language by providing a definition of the officially undefined behavior.

Но мне нравится ход ваших мыслей.

Похоже надо заняться, перевести как нибудь С-шный стандарт :), выложить на Хабре :) .

По второй ссылке представлены другие варианты бага, например, вместо placeholder-а используется Option:
let f: fn(Option<&'d &'d ()>, &'c T) -> &'d T = foo; (Сигнатура helper-а другая).
Возникнуть теоретически может, если писать код с временами жизни и с вложенными ссылками, а не с Rc<RefCell<T>> :)

Сыроватый язык. Недавно столкнулся с transmute из non-mut в mut cсылку c другим типом работал в rust 1.53 и никто не замечал проблемы, а в 1.7 перестало вообще вызываться - оптимизатор просто выкидывал код. Без оптимизатора - поведение соответствует 1.53. Понятно что так нельзя, но тоже хотелось бы видеть warning, а лучше error.

Sorry if you misunderstood my russian. Correct, transmute this way is UB. The point is to have WARNING or ERROR suggesting to fix the issue.

Насколько я вижу, такой ERROR вполне есть:

error: transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
 --> src/main.rs:3:36
  |
3 |     let mut b: &mut i32 = unsafe { std::mem::transmute(&a) };
  |                                    ^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[deny(mutable_transmutes)]` on by default

Можете показать такой код, в котором ERROR не возникает?

Какой мерзкий синтаксис, кто это выдумал? Совсем нечитаемый код.

Это искусственный пример. В реальном коде почти никогда такого не встречается. Реальный код с активным использованием автовывода типов и вовсе похож на typescript.

Вот, например:

pub(super) async fn feed(config: &FeedConfig, par: usize) -> Result<(), anyhow::Error> {
    // Local per-feed state
    let ws_url = config.ws_url;
    let api_url = config.api_url;
    let ws_conn_limiter = Arc::new(RateLimiter::direct(
        Quota::with_period(Duration::from_millis(config.conn_rate_limit_per_ip)).unwrap(),
    ));
    let api_conn_limiter = Arc::new(RateLimiter::direct(
        Quota::with_period(Duration::from_millis(config.conn_rate_limit_per_ip)).unwrap(),
    ));
    let ws_conn_timeout = Duration::from_millis(config.conn_timeout);
    let ws_heartbeat_timeout = Duration::from_millis(config.heartbeat_timeout);
    let (tx, rx) = mpsc::unbounded_future::<(usize, Value)>();

    try_join!(
        // Run connection handlers
        try_join_all((0..par).map(|id| {
            let tx = tx.clone();
            let ws_conn_limiter = ws_conn_limiter.clone();
            conn_handler(
                id,
                tx,
                ws_url,
                ws_conn_limiter,
                ws_conn_timeout,
                ws_heartbeat_timeout,
            )
        })),
        // Run receiver
        conn_receiver(par, rx, api_url, api_conn_limiter),
    )?;

    Ok(())
}

Здесь настраивается пайплайн для получения потока событий из WebSocket API-шки, причем параллельно в несколько коннектов в разные ДЦ (в целях избыточности). События прилетают в виде JSON-строк, которые парсятся параллельно в разных тредах и уже распарсенными передаются в ресивер, который отбрасывает дубли и что-то дальше с ними делает.

Всё равно как арабская вязь. Набор амперсандов скобок стрелок двоеточий. Можно конечно привыкнуть, но выглядит как вырвиглаз бдсм. Такое ощущение, что разработчики языка хотели создать не сообщество разработчиков, а секту посвящённых.

Вы не первый и не последний, кто пишет такое, и здесь всегда возникает один вопрос — предложите более красивый синтаксис без потери функциональности?

Предлагаю синтаксис языка Haskell! Конечно же, измененный под наши нужды. На самом деле я серьезно: в Haskell есть и enum (ADT), и trait (type-class), и closure (lambda), и async/await (do-notation). Он и так уже повлиял на Rust, но все же было бы здорово еще выкинуть хотя бы лишние скобки и точки с запятой. На функциональности это точно никак не сказалось бы. А пока работаем с тем, что имеем.

UPD. Есть даже картинка по теме:

Кадр из видео на канале code_report
Кадр из видео на канале code_report

UPD. Если из-за инверсии код выглядит сильно по-другому, то на Haskell его можно переписать, используя "pipe-оператор", например.

-- pipe
($>) :: a -> (a -> b) -> b
($>) = flip ($)

-- аннотацию типа можно не писать
calculate :: Int -> Int -> Int
calculate bottom top = [bottom..top] $> (filter even) $> sum

Мне хаскель тоже нравится, но как сюда добавить лайфтамы?.. Более того, есть подозрение, что те люди, которые на синтаксис раста жалуются, от хаскеля ещё больше взвоют. В конце-концов большинство языков С-подобные, а плюсовиков и треугольными скобками не напугаешь. Основная претензия к кавычкам лайфтаймов.

Язык С для вас тоже арабская вязь?

Sign up to leave a comment.

Articles