Маjко
Ну можно и так... Хотя разбирать жсоны в компийлтайме... Я не уверен что так можно)
Маjко
Писать руками процедурный времени нет, это не такая большая фича
Маjко
Хорошо б был под это крейт
Leonid 🦇
А есть макрос offsetof для repr(C) структур?
Mykyta
А что, если Голанг придумали для того, чтобы код научились писать нейросеть?
Anonymous
А что, если Раст придумали для того, чтобы было кому троллить голанг, тем самым больше сплочая их сообщество?
Антон
А есть макрос offsetof для repr(C) структур?
На, дарю: macro_rules! offset_of { ($ty:ty, $field:ident) => {{ let struct_: $ty = unsafe { ::std::mem::uninitialized() }; let struct_offset: usize = &struct_ as * const _ as usize; let field_offset: usize = &struct_.$field as * const _ as usize; ::std::mem::forget(struct_); field_offset - struct_offset }} } #[repr(C)] struct Foo { a: u32, b: char, c: u32, } fn main() { println!("{}", offset_of!(Foo, a)); println!("{}", offset_of!(Foo, b)); println!("{}", offset_of!(Foo, c)); }
Leonid 🦇
Но спасибо
Антон
Не хватает mem::forget
А, действительно
Антон
Антон
А гоферов сильно больше, чем растаманов?
По крайней мере, гоферы громче
Dmitry
А гоферов сильно больше, чем растаманов?
Го старше раста раза в 2-3. Он много используется в проде, например в РФ: авито, mail.ru. По нему много вакансий (см. hhru). Так что да, я считаю, что гоферов сильно больше.
Αλεχ
если у тебя типы плывут от того, что ты в цикле переменную чутка объявил то это почти что динамика
Αλεχ
ну короч в любом случае мопед не мой, я просто передаст
Αλεχ
но мнение уважаю, и пока что с ним согласен
𝙽𝚒𝚌𝚔
Ну посмотри в шарпе сколько интерфейсов и методов принимают IEnumerable, а не ArrayList или чего-то такое - и это правильно.
Αλεχ
ну так IEnumerable
Αλεχ
а теперь прикинь, что object
Αλεχ
а что тип должен быть IEnumerable определялось бы внутри по foreach
𝙽𝚒𝚌𝚔
мы исходим из предположения, что сигнатуры методов не пишем?
𝙽𝚒𝚌𝚔
в таком предположении конечно, упадёт где-нибудь в библиотеке и это швах. Но вообще-то вывод типов шикарная вещь например при рефакторинге - ты комментируешь все сигнатуры, меняешь код, потом начинаешь выставлять новые сигнатуры начиная с верхнего уровня - пока не скомпилится. Работает метод прекрасно, и в этом месте хаскелю твёрдая пятюня.
Vladimir
компилятор на самом деле не разиминовывает указатели, если ты обращаешься к полю, а потом берешь ссылку
Vladimir
но да, это ЮБ
Vladimir
но из сишки взято
Leonid 🦇
Если оно в обоих случаях не влияет на кодеген то лучше без уб
Vladimir
а ты думаешь дереференсить неинициализированную память - это не юб?
Vladimir
Я к тому, что хотя в общем случае deref неинициализированной памяти и 0 уб. В данном - нет
Vladimir
Но это моё имхо, а как там на деле - я хз х)
Vladimir
Ну окей, пусть будет он сейфовее
Vladimir
компилятор и то и другое сжимает до movq $4, (%rsp)
Антон
компилятор и то и другое сжимает до movq $4, (%rsp)
Короче, для моего макроса на opt-level=2: push rbp mov rbp, rsp mov eax, 4 pop rbp ret
Vladimir
Проверял?
Да, на плейграунд
Vlad
Почему компилится? struct Foo { a: i32 } fn main() { let mut foo = Foo { a: 1 }; drop(foo); foo.a = 1; } http://play.rust-lang.org/?gist=40b1242b25e6b6119423065c6fc39a06&version=stable&mode=debug&edition=2015
Vlad
playground::main: pushq %rax movl $1, 4(%rsp) movl 4(%rsp), %edi callq core::mem::drop movl $1, 4(%rsp) popq %rax retq
Alexander
Может он считает что это что-то типа int ?
Alexander
Ну да, но может он что-то оптимизировал как бы. Но это просто пальцем с небо.
Alexander
foo.a = foo.a +1 тоже ошибка. Интересно.
Денис
*(&mut foo.a) = 1; — не компилится :)
Vladimir
Видимо Раст понял что это не юзается после, и решил удалить мертвый код
Loo
он такой - бля оно уже замувлено
Loo
ахах
Loo
ебанутиый язык
Vladimir
Что угодно если юзать, кроме = - ругается
Vlad
Мне тут больше всего нравится что будет, есил Дроп заимплементить. Хотя даже хз что больше - ошибка, или её официальное описание https://doc.rust-lang.org/error-index.html#E0383
Vlad
Видимо Раст понял что это не юзается после, и решил удалить мертвый код
Нет, почитай ассемблер в дебаге (я приложил специально). Там есть это присваивание
Roma
хотя б в ирц можно
Roma
Это не баг
ну интересно чо такое
Cat
если оно мувается, то почему не баг?
Alexander
Может там какой-то ref аыдаётся в дроп. Но что-то врядли.
Vladimir
Может там какой-то ref аыдаётся в дроп. Но что-то врядли.
нет, в дроп там все правильно выдается
Alexander
нет, в дроп там все правильно выдается
Ну давай тогда говори почему.
Vladimir
Ну мое имхо что это баг. Хоть раст и понимает что foo.b=1 не имеет побочных эффектов, всеравно то что он не ругается имхо баг бороучекера
Vlad
Если считать это багом, то баг в языке, а не в реализации. Ибо поведение задокументировано
Vladimir
а где задокументировано?
Vladimir
если не имеет побочных эффектов, то зачем вставляет в llvm?
про это и речь, по этому и считаю что баг
Vlad
а где задокументировано?
Я бы счел это, как и сам факт существования E0383 https://doc.rust-lang.org/error-index.html#E0383
Vladimir
ну имхо это ошибка не говорит ничего про то что "дроп" тут играет роль, так что поидее такое поведение и без дропа должно быть
Roma
ну и с i32 допустим не баг, а если там чот без копи, то как в чёрную дыру муваешь
Roma
ну без копи оно не даст
http://play.rust-lang.org/?gist=a7c691ced211ffe47e8c7aad264ad013&version=stable&mode=debug&edition=2015
Roma
даёт, bar мувнуто в никуда
𝙽𝚒𝚌𝚔
Немного интереснее пример: #[derive(Debug)] struct Foo { a: i32 } fn main() { let mut x = Foo { a: 1 }; let random = Rc::new(RefCell::new(IsaacRng::new_from_u64(123))); if random.borrow_mut().gen() { drop(x) // x gets moved out; make x uninit. } else { println!("{:?}", x); drop(x) // x gets moved out; make x uninit. } x.a = 1; // x was uninit; just overwrite. // x goes out of scope; x was init; Drop x! } Из https://doc.rust-lang.org/nomicon/drop-flags.html
Vladimir
ну тоди точно баг
𝙽𝚒𝚌𝚔
То есть механизм такой: drop помечает память как uninitialized