Книжка по UB
От: LaptevVV Россия  
Дата: 12.08.25 04:02
Оценка: 99 (11) +2
Я тут давал адрес репы на гитхабе об UB
https://github.com/Nekrolm/ubbook

Автор собрался с силами, и написал книжку!
https://bhv.ru/product/ekskurs-v-neopredelennoe-povedenie-c/

А научным редактором и соавтором у него стал Андрей Карпов — основатель PVS

Рекомендую!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 16:31
Оценка: +2
Здравствуйте, LaptevVV, Вы писали:

LVV>Рекомендую!


Полистал немного. Об этом надо писать поэму, а не книжку в прозе.

#include <string>

int main() {
    std::string s;
    s += 48;    // неявное приведение к char.
    s += 1000;  // а тут еще и с переполнением, очень неприятным
                // на платформе с signed char.
    s += 49.5;  // опять-таки неявное приведение к char
}


Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
Re[2]: Книжка по UB
От: B0FEE664  
Дата: 12.08.25 17:17
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Полистал немного. Об этом надо писать поэму, а не книжку в прозе.

Да там много интересного.
Вот грабли, на которые я ещё не наступал:
const int max_v = 10;

void fun(int y) 
{
   const int max_v = [&]{
       // локальный max_v перекрывает глобальный max_v
       return std::min(max_v, y);
   }();
   ...
}
И каждый день — без права на ошибку...
Re[2]: Книжка по UB
От: LaptevVV Россия  
Дата: 12.08.25 17:40
Оценка: +1
Pzz>Полистал немного. Об этом надо писать поэму, а не книжку в прозе.
Pzz>
Pzz>#include <string>
Pzz>int main() {
Pzz>    std::string s;
Pzz>    s += 48;    // неявное приведение к char.
Pzz>    s += 1000;  // а тут еще и с переполнением, очень неприятным
Pzz>                // на платформе с signed char.
Pzz>    s += 49.5;  // опять-таки неявное приведение к char
Pzz>}
Pzz>

Pzz>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
Да.
Мне просто в голову такая хрень никогда не приходила! Ни разу в жизни такое не писал...
А оно вон оно чо, Михалыч!

Проверил на MinGW gcc 14.2 — компилируется!
Предупреждение выдает только на строку с 1000:
warning: overflow in conversion from 'int' to 'char' changes value from '1000' to '-24' [-Woverflow]

Даже на 49.5 — ничего не пишет!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Книжка по UB
От: so5team https://stiffstream.com
Дата: 12.08.25 18:23
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.


Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.

Эти же грабли прямиком оттуда унаследованы:
int main()
{
    char s[10];
    s[0] = 48;
    s[1] = 1000;
    s[2] = 49.5;
}

https://wandbox.org/permlink/Oaqs7fuRXVZNYkco
Re[3]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 18:30
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

Pzz>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.

LVV>Да.
LVV>Мне просто в голову такая хрень никогда не приходила! Ни разу в жизни такое не писал...
LVV>А оно вон оно чо, Михалыч!

Там самая мякотка — в главе про неработающий синтаксис.

struct Timer {
    int val;
    explicit Timer(int v = 0) : val(v) {}
};

struct Worker {
    int time_to_work;

    explicit Worker(Timer t) : time_to_work(t.val) {}

    friend std::ostream& operator << (std::ostream& os, const Worker& w) {
        return os << "Time to work=" << w.time_to_work;
    }
};

int main() {
    // ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
    Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!

    std::cout << w; // имя функции неявно преобразуется к указателю, который неявно преобразуется к bool
    // будет выведено 1 (true)
}
Re[3]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 18:44
Оценка: +2
Здравствуйте, so5team, Вы писали:

Pzz>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.


S>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.


В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.
Re[4]: Книжка по UB
От: LaptevVV Россия  
Дата: 12.08.25 18:48
Оценка:
Pzz>Там самая мякотка — в главе про неработающий синтаксис.
Pzz>
...
Pzz>    // ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
Pzz>    Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!
Pzz>

Ну, я как привык смолоду писать попроще, через равенство — так и пишу.
Сейчас приходится переучиваться на {}
Но вообще — да.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 18:51
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Ну, я как привык смолоду писать попроще, через равенство — так и пишу.

LVV>Сейчас приходится переучиваться на {}
LVV>Но вообще — да.

Это я выдернул первое, что под руку подвернулось. Там много весёлого.

Я понимаю, что половина этого в Си тоже есть. Но в Си нет всех этих прекрасных автоматизмов, которые способны превратить простую и понятную ошибку в хитрую или запутанную.
Re[3]: Книжка по UB
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.08.25 18:53
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Вот грабли, на которые я ещё не наступал:

BFE>
BFE>const int max_v = 10;

BFE>void fun(int y) 
BFE>{
BFE>   const int max_v = [&]{
BFE>       // локальный max_v перекрывает глобальный max_v
BFE>       return std::min(max_v, y);
BFE>   }();
BFE>   ...
BFE>}
BFE>


Это ещё с сишечки по-моему так. В любом случае, компилятор тебе скажет, как минимум предупреждение, что одна переменная скрывает другую. Но, конечно, если у тебя при компиляции "кучи ненужных варнингов" (c) (tm), но будут грабли.
Маньяк Робокряк колесит по городу
Re[4]: Книжка по UB
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.08.25 18:55
Оценка: +2
Здравствуйте, Pzz, Вы писали:


Pzz>Там самая мякотка — в главе про неработающий синтаксис.


Pzz>
Pzz>int main() {
Pzz>    // ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
Pzz>    Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!

Pzz>    std::cout << w; // имя функции неявно преобразуется к указателю, который неявно преобразуется к bool
Pzz>    // будет выведено 1 (true)
Pzz>}
Pzz>


Это все уже лет 30 как знают
Маньяк Робокряк колесит по городу
Re[4]: Книжка по UB
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.08.25 18:56
Оценка:
Здравствуйте, Pzz, Вы писали:

S>>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.


Pzz>В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.


А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?
Маньяк Робокряк колесит по городу
Re[3]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 18:57
Оценка: +2
Здравствуйте, B0FEE664, Вы писали:

Pzz>>Полистал немного. Об этом надо писать поэму, а не книжку в прозе.

BFE>Да там много интересного.

Мне еще вот такое очень понравилось:

// пример взят из блога https://mohitmv.github.io/blog/Shocking-Undefined-Behaviour-In-Action/
int main() {
  char buf[50] = "y";
  for (int j = 0; j < 9; ++j) {
    std::cout << (j * 0x20000001) << std::endl;
    if (buf[0] == 'x') break;
  }
}


Тут компилятор решает вынести умножение из тела цикла. Заменяет ++j на j += 0x20000001, ну и верхнюю границу, девятку, тоже умножает на 0x20000001. А что, имеет право, целочисленное переполнение для знаковых типов — это UB. В итоге цикл на 9 оборотов становится бесконечным.
Re[5]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 19:00
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.


M>А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?


Здесь — ничем.

А вот когда к сишным (весма вольным и дурным) правилам преобразования типов добавляется сипплюсплюсная идея вложить в тип глубокий смысл, позволив через оверлоадинг приделать к разным типам разное поведение для одинаково выглядещих действий, жизнь становится уже весьма забавной.
Re[6]: Книжка по UB
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 12.08.25 19:12
Оценка:
Здравствуйте, Pzz, Вы писали:

M>>А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?


Pzz>Здесь — ничем.


Pzz>А вот когда к сишным (весма вольным и дурным) правилам преобразования типов добавляется сипплюсплюсная идея вложить в тип глубокий смысл, позволив через оверлоадинг приделать к разным типам разное поведение для одинаково выглядещих действий, жизнь становится уже весьма забавной.



Дурные правила преобразования типов работают только для интегральных типов и плавучки. Это полностью наследие сишечки. Для типов, в которые вложен глубокий смысл, всё весьма строго.
Маньяк Робокряк колесит по городу
Re[4]: Книжка по UB
От: so5team https://stiffstream.com
Дата: 12.08.25 19:33
Оценка: 2 (1) +1
Здравствуйте, Pzz, Вы писали:

Pzz>>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.


S>>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.


Pzz>В сишечке это не имеет таких последствий.


Вот объясните мне, а то я не понимаю это что: глупость, двойные стандарты или и то, и другое?
Ибо когда в Си из-за дебильных правил приведения типа хз какой char автоматически и неявно генерируется из double-литерала, то это OK.
А вот когда в С++ в точности тоже самое происходит из-за тех же самых (именно что тех же самых, унаследованных из Си) правил -- то это уже мать-мать-мать-перемать.

Ну вот как это в одной башке уживается?

Pzz>К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.


Вы, видимо, забыли (а может никогда и не знали) старый афоризм: Си позволяет вам выстрелить себе в ногу, в C++ это сделать сложнее, но когда вы это таки сделаете, то вам отрывает нахрен сразу обе ноги.

Ну и чтобы еще набросить на вашу пустую седую голову: в современном С++ хотя бы можно написать s += char{49.5} и получить ошибку компиляции. А вот что здесь может предложить Си?
Re[5]: Книжка по UB
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.08.25 19:36
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>Ну и чтобы еще набросить на вашу пустую седую голову: в современном С++ хотя бы можно написать s += char{49.5} и получить ошибку компиляции. А вот что здесь может предложить Си?


Мы с вами уже договаривались, что либо вы не хамите, либо мы не общаемся.

Прощайте!
Re: Книжка по UB
От: __kot2  
Дата: 13.08.25 06:12
Оценка:
на озоне, кстати, тоже продается. заказал
Re: Книжка по UB
От: Privalov  
Дата: 13.08.25 07:55
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Рекомендую!


Вспомнилось. Во времена Фортрана литературы "Грабли в Фортране" было полно. Мы даже что-то проверяли, когда учились. Порчу константы или беспорядочное использование COMMON, особенно безымянных. Зато в реальной работе граблей избегать удавалось.
А на C/C++ мне довелось написать совсем немного кода. Всякие там JNI и вставки к фортрановскому проекту.
Но судя по опыту работы с Фортраном, такая литература должна быть полезной.
Re[2]: Книжка по UB
От: LaptevVV Россия  
Дата: 13.08.25 09:19
Оценка:
P>Вспомнилось. Во времена Фортрана литературы "Грабли в Фортране" было полно. Мы даже что-то проверяли, когда учились. Порчу константы или беспорядочное использование COMMON, особенно безымянных. Зато в реальной работе граблей избегать удавалось.
Да, это я тоже знаю...
P>А на C/C++ мне довелось написать совсем немного кода. Всякие там JNI и вставки к фортрановскому проекту.
P>Но судя по опыту работы с Фортраном, такая литература должна быть полезной.
Она очень полезна.
Для начинающих — откровение увидеть, как сложение 2 положительных становится отрицательным.
А в этой книжке поглубже, для мидлов.
Неявные преобразования — зло абсолютное.
Теперь у меня для студентов есть аргументированный источник примеров.
Не совсем уж тривиальных.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.