- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
// https://github.com/CVC4/CVC4/blob/14b9dbaa0c9e8dce52d1a28595dc1cc80756abed/src/expr/pickler.cpp
static Block mkBlockBody4Chars(char a, char b, char c, char d) {
Block newBody;
newBody.d_body.d_data = (a << 24) | (b << 16) | (c << 8) | d;
return newBody;
}
static char getCharBlockBody(BlockBody body, int i) {
Assert(0 <= i && i <= 3);
switch(i) {
case 0: return (body.d_data & 0xff000000) >> 24;
case 1: return (body.d_data & 0x00ff0000) >> 16;
case 2: return (body.d_data & 0x0000ff00) >> 8;
case 3: return (body.d_data & 0x000000ff);
default:
Unreachable();
}
return '\0';
}
// ...
void PicklerPrivate::toCaseString(Kind k, const std::string& s) {
d_current << mkConstantHeader(k, s.size());
unsigned size = s.size();
unsigned i;
for(i = 0; i + 4 <= size; i += 4) {
d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], s[i + 3]);
}
switch(size % 4) {
case 0: break;
case 1: d_current << mkBlockBody4Chars(s[i + 0], '\0','\0', '\0'); break;
case 2: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1], '\0', '\0'); break;
case 3: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], '\0'); break;
default:
Unreachable();
}
}
Очередное переизобретение какой-то байтоебской поеботы типа ntohl(). И вообще, тут UB.
Hu3KoypoBHeBblunemyx 21.02.2019 21:27 # +2
Elvenfighter 22.02.2019 19:19 # 0
P.S. s.size() >= std::numeric_limits<unsigned>::max() - 4 наверняка вылетит по памяти значительно раньше. Но "cover my ass" assert можно и вставить.
bormand 22.02.2019 19:37 # 0
6E3yMHblu_nemyx 22.02.2019 19:42 # 0
Что-то типа (uint32_t)a << 24 или static_cast?
bormand 22.02.2019 19:52 # +1
Но int во-первых хуй знает какого размера. А во-вторых сдвиг знакового числа влево до упора ничем хорошим не закончится (даже при 32-битном инте).
6E3yMHblu_nemyx 22.02.2019 19:57 # 0
bormand 22.02.2019 20:00 # 0
6E3yMHblu_nemyx 22.02.2019 20:24 # +2
UB существует только в «C» и «C++». В других языках программирования никаких UB нет, именно поэтому я за другие языки.
bormand 22.02.2019 20:24 # 0
1) число знаковое и может быть отрицательным
2) его двигают влево
Hu3KoypoBHeBblunemyx 23.02.2019 08:35 # 0
"UB" существует во всех низкоуровневых языках с претензией на переносимость и у которых больше одной реализации. Даже у разных процов линейки "x86" в некоторых ситуациях было разное поведение на разных процах (щас точно не помню все, помню что была хуита с чтением слова по адресу FFFF, в одних процах байт читался из следующего сегмента, в других из начала текущего, остальных нагуглить/наяндексить не могу, они советуют мне посмотреть "Свойства системы"), так в стародавние времена определяли на каком проце мы запущены.
bormand 23.02.2019 10:37 # 0
UB хуже. С ним даже доки по железу и конпелятору тебе не помогут.
И, на самом деле, UB есть и во вполне высокоуровневых языках. Просто они там довольно очевидные. Гонки между потоками, к примеру.
Hu3KoypoBHeBblunemyx 23.02.2019 10:51 # 0
Мда, надо бы как-нибудь выделить денёк, чтобы выспаться.
bormand 24.02.2019 07:39 # 0
А уж в железе сколько UB'ов...
guest8 24.02.2019 14:03 # −999
6E3yMHblu_nemyx 24.02.2019 17:10 # 0
В первых пятивольтовых микросхемах ТТЛ входной сигнал в интервале от 2,5 вольт до 5 воспринимался как единица, от 0 до 0,5 вольт –— как ноль, а вот сигнал в интервале 0,5...2,5 вольт был UB.
bormand 24.02.2019 20:41 # +1
bormand 24.02.2019 20:50 # +1
cmepmop 22.02.2019 20:32 # 0
bormand 22.02.2019 20:34 # +2
Hu3KoypoBHeBblunemyx 23.02.2019 08:38 # 0
guest8 23.02.2019 19:21 # −999
guest8 23.02.2019 19:51 # −999
bormand 23.02.2019 20:00 # 0
А такое решение довольно часто юзают для интерпретаторов.
guest8 23.02.2019 20:04 # −999
bormand 23.02.2019 20:10 # +1
В какой-то реализации лишпа вроде 2 бита откусывали.
guest8 23.02.2019 20:13 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 20:15 # +1
guest8 23.02.2019 20:16 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 20:21 # 0
guest8 23.02.2019 20:26 # −999
bormand 23.02.2019 20:29 # 0
guest8 23.02.2019 20:30 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 20:30 # 0
guest8 23.02.2019 20:32 # −999
bormand 23.02.2019 20:35 # 0
guest8 23.02.2019 20:37 # −999
bormand 23.02.2019 20:38 # 0
guest8 23.02.2019 20:39 # −999
bormand 23.02.2019 20:43 # 0
guest8 23.02.2019 20:44 # −999
guest8 23.02.2019 20:40 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 20:42 # 0
guest8 23.02.2019 20:43 # −999
bormand 23.02.2019 20:44 # 0
Hu3KoypoBHeBblunemyx 23.02.2019 20:48 # +2
Открою секрет, струкьуры в сишке фиксированного размера, никакой sizeof нигде тебе не будет читать поля структуры.
> передачу по значению
Жто же питно, в нём всё в куче, функции принимают только оказатели.
> массив из такой хуни тоже не сделать
указатели.
guest8 23.02.2019 20:52 # −999
bormand 23.02.2019 20:59 # 0
Если хак приносит профит - вай нот?
guest8 23.02.2019 21:21 # −999
bormand 23.02.2019 21:22 # 0
guest8 23.02.2019 21:24 # −999
OCETuHCKuu_nemyx 24.02.2019 01:17 # 0
1024-- 24.02.2019 01:15 # 0
Или он проходит по стандарту и так?
Что я вижу:
* Выход за границу массива
* Игнорирование перестановки полей структуры компилятором
* Игнорирование паддингов, в которые нельзя писать
Хотя, я всех тонкостей, разумеется, не знаю. Но, если учесть капризность стандарта и безумные правила для UB, любой другой код в аналогичной ситуации наткнулся бы на одну из этих проблем и улетел бы в UB.
bormand 24.02.2019 05:32 # 0
А переставлять поля и так нельзя.
Hu3KoypoBHeBblunemyx 23.02.2019 21:03 # 0
А теперь приведи мне свою реализацию где sizeof бы работал как ты кочешь.
guest8 23.02.2019 21:14 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:20 # 0
guest8 23.02.2019 21:22 # −999
guest8 23.02.2019 21:25 # −999
bormand 23.02.2019 21:05 # +2
guest8 23.02.2019 21:15 # −999
gost 23.02.2019 21:06 # 0
С чего ты это взял?
Hu3KoypoBHeBblunemyx 23.02.2019 21:10 # 0
gost 23.02.2019 21:14 # 0
guest8 23.02.2019 21:17 # −999
guest8 23.02.2019 21:14 # −999
gost 23.02.2019 21:16 # 0
>>>
Размер long + sizeof(digit), что не так?
guest8 23.02.2019 21:18 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:23 # 0
guest8 23.02.2019 21:25 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:16 # 0
guest8 23.02.2019 21:18 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:22 # 0
guest8 23.02.2019 21:23 # −999
guest8 23.02.2019 21:27 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:32 # 0
guest8 23.02.2019 21:35 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:40 # 0
guest8 23.02.2019 21:22 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:33 # 0
guest8 23.02.2019 21:39 # −999
Hu3KoypoBHeBblunemyx 23.02.2019 21:51 # +1
bormand 23.02.2019 22:48 # 0
Бородатым сишникам не нравится выделять по 2 куска памяти на каждый чих, поэтому и юзают такую хуйню для всяких строк, блобов да длинных чисел.
Вся суть в аллокации хедера и данных одним блоком. А идиома с массивом - просто для удобства, чтобы меньше кастовать. Можешь выкинуть массив и переименовать структуру в number_header.
З.Ы. Даже в крестах make_shared() делает нечто подобное чтобы склеить счётчики и объект в одну аллокацию.
Hu3KoypoBHeBblunemyx 23.02.2019 22:58 # 0
bormand 23.02.2019 20:48 # 0
bormand 22.02.2019 20:29 # +1
Да похуй на UB, оно вообще не работает (отрицательное d засрёт своим знаковым битом всё остальное). Или у автора там беззнаковый чар?
6E3yMHblu_nemyx 23.02.2019 14:28 # 0
Кстати, у некоторых кококомпиляторов есть переключатель «signed char/unsigned char».
Hu3KoypoBHeBblunemyx 23.02.2019 16:09 # 0
1024-- 23.02.2019 19:19 # 0
1024-- 23.02.2019 19:18 # 0
Т.е. это на случай, когда пишут не signed char, не unsigned char, а просто char?
guest8 23.02.2019 19:20 # −999
1024-- 23.02.2019 19:31 # 0
gost 23.02.2019 19:47 # +3
6E3yMHblu_nemyx 23.02.2019 20:14 # 0
guest8 23.02.2019 20:15 # −999