#%D0%BD%D0%B5%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D0%BE%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5

2025-10-16

Книга «Экскурс в неопределённое поведение C++». Секреты укрощения единорога

Привет, Хабр. С гордостью, триумфом и трепетом хотим рассказать вам об одной из наших флагманских новинок, вышедшей в пылающем июле — книге « Экскурс в неопределённое поведение C++ ». Cегодня книжные полки изобилуют нестареющими пособиями по C++. Этот язык чрезвычайно важен не только в разработке игр, финансового софта и встраиваемого ПО, но и как основной материал для изучения алгоритмов. Именно поэтому мы даже выпустили две книги-билингвы по алгоритмам, в которых код на C++ соседствует с идентичным ему кодом на Python. Это наш многолетний бестселлер « Алгоритмический тренинг. Решения практических задач на Python и C++ » Максима Иванова и недавняя новинка « Базовые алгоритмы. Реализации на Python и C++ на примере классических игр » Павла Довгалюка. Но язык C++ не только очень полезен, но и опасен, так как на этапе преобразования исходного кода в машинный многие решения отдаются на откуп компилятору. Поскольку компилятор в большинстве режимов изначально заточен на оптимизацию кода, он регулярно привносит в код C++ непредсказуемые и порой необъяснимые варианты неопределённого поведения (UB, Undefined Behavior). Титаническую работу по систематизации неопределённого поведения в C++ проделал уважаемый Дмитрий Свиридкин @Nekrolm . В настоящее время он работает инженером по программированию встраиваемых систем в отделе Cloudfront Compute компании AWS. Дмитрий преподавал курсы по Linux и C++ в Санкт-Петербургском государственном университете и Высшей школе экономики, а также имеет богатейший послужной список , в котором есть и олимпиады по информатике, и машинное обучение, и программирование прошивок и, конечно же, выжимание последних капель производительности из самого неукротимого облачного железа. Некоторое время его заметки публиковались на сайте компании PVS-Studio, разрабатывающей известный российский статический анализатор кода.

habr.com/ru/companies/bhv_publ

#undefined_behavior #неопределённое_поведение #C++ #оптимизация #программирование

2025-10-14

[Перевод] Подробно о неопределённом поведении в С и C++

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

habr.com/ru/articles/956522/?u

#компиляторы #неопределённое_поведение #C #встраиваемые_системы #статический_анализ #c++

2025-10-14

[Перевод] Подробно о неопределённом поведении в С и C++

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

habr.com/ru/articles/956522/

#компиляторы #неопределённое_поведение #C #встраиваемые_системы #статический_анализ #c++

2025-08-29

Что делать, если ваш слон думает, что он баг?

Мы окунулись в веб-разработку и нашли там необычное животное. Это был слон с повадками бага. Мы изучили код проекта PHP и поняли, в чём дело. Давайте вместе посмотрим на необычные случаи, которые могут привести к неожиданным результатам.

habr.com/ru/companies/pvs-stud

#программирование #php #c #c++ #статический_анализ #static_analysis #ошибки_в_программе #memory_allocation #undefined_behavior #неопределённое_поведение

2025-06-03

std::launder: зачем и когда нужен

Привет, Хабр! В этой статье разберём мутный, но крайне важный инструмент ‒ std::launder . Мы поглядим, зачем его протащили в C++17 и что компилятор делает, когда видит launder.

habr.com/ru/companies/otus/art

#c++ #C++17 #неопределённое_поведение #lifetime_объекта #оптимизации_компилятора #указатели

2025-02-13

[Перевод] Избавляемся от UB в memcpy

Неопределённое поведение (undefined behavior, UB) в языке программирования C — постоянный источник жарких споров между программистами. С одной стороны, UB может быть важным для оптимизаций компилятора. С другой стороны, оно упрощает появление багов, которые приводят к проблемам безопасности. Хорошая новость: N3322 был принят для C2y, что позволит устранить неопределённое поведение из этого конкретного участка языка C и сделать всё показанное ниже чётко определённым: memcpy(NULL, NULL, 0); memcmp(NULL, NULL, 0); (int *)NULL + 0; (int *)NULL - 0; (int *)NULL - (int *)NULL;

habr.com/ru/articles/866088/

#gcc #clang #llvm #неопределённое_поведение #undefined_behavior

2025-01-28

Путеводитель C++ программиста по неопределённому поведению

Вашему вниманию предлагается полный список разделов электронной книги (12 из 11 :)), посвящённой неопределённому поведению. Книга не является учебным пособием и рассчитана на тех, кто уже хорошо знаком с программированием на C++. Это своего рода путеводитель C++ программиста по неопределённому поведению, причём по самым его тайным и экзотическим местам. Автор книги — Дмитрий Свиридкин, редактор — Андрей Карпов.

habr.com/ru/companies/pvs-stud

#Неопределённое_поведение #undefined_behavior #C #C++ #Си #Си++ #баги #ошибки_в_коде #ошибки_программистов #программирование #компиляторы

2024-08-23

[Перевод] Что значит инициализировать int в C++?

Недавно я получил по почте от Сэма Джонсона этот вопрос. Вот слегка отредактированное письмо Сэма: «Возьмём для примера этот код в локальной области видимости функции: int a; a = 5; Многие люди считают, что инициализация происходит в строке 1, потому что веб-сайты наподобие cppreference дают такое определение: "Инициализация переменной предоставляет его начальное значение на момент создания". Однако я убеждён, что инициализация происходит в строке 2, потому что [в разных хороших книгах по C++] инициализация определяется как первое существенное значение, попадающее в переменную. Можете ли вы сказать, какая строка считается инициализацией?» Отличный вопрос. На Cppreference написано правильно, и для всех классовых типов ответ прост: объект инициализируется в строке 1 вызовом его стандартного конструктора. Но (а вы ведь знали, что будет «но») для локального объекта фундаментального встроенного типа наподобие int ответ будет... чуть более сложным. И именно поэтому Сэм задал этот вопрос, ведь он знает, что язык достаточно свободно обращается с инициализацией таких локальных объектов по историческим причинам, имевшим в то время смысл. Короткий ответ: вполне допустимо говорить, что переменная получает своё исходное значение в строке 2. Но заметьте, что я намеренно не сказал «Объект инициализируется в строке 2», к тому же и код, и этот ответ обходят молчанием более важный вопрос: «Ну ладно, а что, если код между строками 1 и 2 попробует считать значение объекта?»

habr.com/ru/articles/835170/

#инициализация #неопределённое_поведение #переменные #integer #стандарты_и_спецификации

2024-07-15

[Перевод] Конструктора у меня нет, а инициализироваться надо

Так прошло три дня. В комнате темно и холодно, но мониторы слепят. Ты дезориентирован настолько, как будто тебя кидает из одного диссоциативного эпизода в другой. Тебя то и дело пробивает нервный смех, хотя смеяться нечему. Как я здесь оказался? В чём моя вина? Главная ошибка была в том, что ты в это вообще ввязался — в этом никаких сомнений. Ещё когда я впервые взялся проходить курс по C++ несколько лет назад, меня учили, что, если я не предоставлю собственного конструктора, то компилятор сам подберёт ему замену — своего рода конструкторы, действующие по умолчанию. Я решил подробнее в этом разобраться, особенно меня волновали случаи, которые выглядят примерно так:

habr.com/ru/articles/828936/

#gcc #Clang #C++ #инициализация #неопределённое_поведение

2024-07-09

[Перевод] UB или не UB – вот в чём вопрос: как gcc и clang обрабатывают статически известное неопределённое поведение

Недавно у нас в команде зашла дискуссия о неопределённом поведении (UB) в C. Напомню для тех, кто не знает: если мы пишем такой код, эффект от выполнения которого (и события в процессе его выполнения) строго не определён в спецификации языка, то возникает неопределённое поведение. Таким образом, встретив такой код, компилятор может действовать по собственному усмотрению, и нет никаких гарантий, что выполнение этого кода пойдёт по предсказуемому пути. Следовательно, нужно избегать неопределённого поведения любой ценой, поскольку мало того, что оно может приводить к глюкам программы, но и часто становится источником уязвимостей и угрозой безопасности. Примеры кода, в котором проявляется неопределённое поведение: выход за границы массива при его индексировании, целочисленное переполнение, деление на ноль, разыменование указателя на null [1] . Компиляторы нередко пользуются неопределённой семантикой языка, чтобы делать те или иные допущения о программе. Например, если написать что-то вроде int x = y/z , компилятор может предположить, что z не может быть равно нулю, так как деление на ноль приводит к неопределённому поведению, а программист явно не собирался писать такой код. На основе этой информации он может попытаться далее оптимизировать программу так:

habr.com/ru/articles/827752/

#С++ #gcc #clang #неопределённое_поведение #программирование

Client Info

Server: https://mastodon.social
Version: 2025.07
Repository: https://github.com/cyevgeniy/lmst