Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
И сейчас можно чекать UB через UndefinedBehaviorSanitizer
Вы пишите, что «почти любая строка в C++ потенциально может стать источником UB» — сомневаюсь, что это правда.Почти любая арифметика может привести к переполнению. Переполнение — это UB.
Если же это так, то это ошибка дизайна языка.Нет, это специфика предметной области. Просто то, что, скажем, в Java приводит к выбросу какого-нибудь
ArrayIndexOutOfBoundsException в C/C++ может привести к более серьёзным последствиям. Но также как почти любая строка в Java может выкинуть какой-нибудь NullPointerException, ArrayIndexOutOfBoundsException или ещё чего похуже, так любая строчка в C/C++ при «неподходящих» аргументах может привести к UB.Проблема С++ это то, что компилятор считает, что программист очень умный и его программа без UB и поэтому ее можно агрессивно оптимизировать.Нет. Компилятор в Java так не считает, но бинарный поиск всё равно частенько не работает. «Тупой» и «предсказуемый» компилятор — вовсе не гарантия того, что ваша программа будет работать без ошибок…
void process_something(int size) {
// Catch integer overflow.
if (size > size+1)
abort();
...
// Error checking from this code elided.
char *string = malloc(size+1);
read(fd, string, size);
string[size] = 0;
do_something(string);
free(string);
}
void process_something(int *data, int size) {
char *string = malloc(size+1);
read(fd, string, size);
string[size] = 0;
do_something(string);
free(string);
}В универсальном ассемблере нельзя сказать, как будет обрабатываться переполнение на конкретном процессоре.И именно поэтому переполнение — это UB.
А при программировании на ассемблере для конкретного процессора — можно.А это — уже неважно. С и C++ — это инструменты для написания переносимого кода. Если вы пытаетесь при программировании на них использовать ваше знание конкретного процессора — вас ждут сюрпризы.
а давайте обсудим пример отсюда:Давайте.
blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
// Catch integer overflow.
if (size > size+1)
abort();
Типичный код написанный мистером компилятор-писали-дураки-я знаю-как-лучше. Кто заставлял вместо простого и понятного:// Catch integer overflow.
if (size = INT_MAX)
abort();
писать вот то, что там написали? Желание выпендриться? И вообще: почему там int, а не size_t? Чтобы было веселее?cmp).Некоторые разработчики, считающие себя умнее компилятора (и бывшие, в прошлом, реально «умнее» какого-нибудь Turbo C), «нарываются на неприятности» — после чего поднимают «вселенский вой» на форумах.
Переполнение — это UB.
[CppCon 2017] Бьёрн Страуструп: Изучение и преподавание современного C++