Информация об изменениях

Сообщение Re[15]: Сырые указатели в С++1х от 07.04.2023 5:26

Изменено 07.04.2023 7:38 so5team

Re[15]: Сырые указатели в С++1х
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Отсюда вопрос: на каком основании нам нужно пристально фиксироваться именно на этом варианте UB, а не на всех остальных возможных?


Не уверен что понимаю суть вопроса. Для меня он выглядит так "в C++ есть 101 способ выстрелить себе в ногу, так зачем нам обсуждать один конкретный, если остается еще 100?"

Если мы не стреляем себе в ногу одним конкретным способом (а именно не пытаемся убедить самих себя в наличии такой штуки, как нулевая ссылка), то у нас остается уже не 101, а всего 100 способов.

ЕМ>Что говорит статистика о частоте UB именно из-за подобных ссылок?


Давайте еще выводить значение sin(pi) на основании опроса людей на улице.

S>>у вас нет такой штуки, как нулевая ссылка. Легально, по крайней мере.


ЕМ>А я где-то предлагал считать такой случай легальным?


Вот здесь
Автор: Евгений Музыченко
Дата: 05.04.23
.

ЕМ>Я такой архитектуры даже представить не могу.


А я вот не могу представить, как можно демонстрировать такую непроходимую ту ограниченность, но при этом писать связные тексты в обсуждениях и, вроде как, даже писать работающий код. Однако ж...

Работать с указателем после его освобождения нельзя ни в Си, ни в C++. Это UB. Точка.
Разыменование нулевого указателя -- это UB. Точка.

Компиляторы могут не эксплуатировать какой-то UB десятилетиями. Как это было, например, с компиляторами C++ вот с таким UB до C++17:
alignas(T) char buffer[sizeof(T)];
file.read(buffer, sizeof(buffer));
T * data_object = reinterpret_cast<T*>(buffer);

Только вот UB это быть не переставало. И после добавления в C++17 std::launder подобный код может оказаться поломанным в любой момент.

ЕМ>А что делать, например, с традиционным для C и "неканонического" C++ способом перебора элементов массива, когда указателю присваивается адрес первого элемента и увеличивается до тех пор, пока не выйдет за пределы массива — как минимум, на адрес, следующий за последним элементом, но может выйти и дальше, если перебор не последовательный?


Если руки из жопы, то разве что отдать этот код тем, у кого они растут из правильного места.

ЕМ>Из каких соображений Вы заключаете, что вероятность именно такого поведения выше вероятности присутствия в коде скрытых ошибок, или ошибок компилятора, или ошибок системы, в которой будет работать код?


Здесь важна не вероятность, а зона ответственности. Ошибки в компиляторе или run-time библиотеке вне моей зоны ответственности. А вот написанный мной код -- в моей. И если мой код теряет работоспособность из-за моих ошибок, то отвечать за это мне.

Прецеденты того, как работавший в прошлом код перестал быть таковым из-за оптимизаций в очередной версии компилятора, уже были. Очень наивно предполагать, что подобного не может произойти в будущем.
Re[15]: Сырые указатели в С++1х
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Отсюда вопрос: на каком основании нам нужно пристально фиксироваться именно на этом варианте UB, а не на всех остальных возможных?


Не уверен что понимаю суть вопроса. Для меня он выглядит так "в C++ есть 101 способ выстрелить себе в ногу, так зачем нам обсуждать один конкретный, если остается еще 100?"

Если мы не стреляем себе в ногу одним конкретным способом (а именно не пытаемся убедить самих себя в наличии такой штуки, как нулевая ссылка), то у нас остается уже не 101, а всего 100 способов.

ЕМ>Что говорит статистика о частоте UB именно из-за подобных ссылок?


Давайте еще выводить значение sin(pi) на основании опроса людей на улице.

S>>у вас нет такой штуки, как нулевая ссылка. Легально, по крайней мере.


ЕМ>А я где-то предлагал считать такой случай легальным?


Вот здесь
Автор: Евгений Музыченко
Дата: 05.04.23
.

ЕМ>Я такой архитектуры даже представить не могу.


А я вот не могу представить, как можно демонстрировать такую непроходимую ту ограниченность, но при этом писать связные тексты в обсуждениях и, вроде как, даже писать работающий код. Однако ж...

Работать с указателем после его освобождения нельзя ни в Си, ни в C++. Это UB. Точка.
Разыменование нулевого указателя -- это UB. Точка.

Компиляторы могут не эксплуатировать какой-то UB десятилетиями. Как это было, например, с компиляторами C++ вот с таким UB до C++17 C++20:
alignas(T) char buffer[sizeof(T)];
file.read(buffer, sizeof(buffer));
T * data_object = reinterpret_cast<T*>(buffer);

Только вот UB это быть не переставало. И после добавления в C++17 std::launder принятия C++20 подобный код может оказаться поломанным в любой момент.

ЕМ>А что делать, например, с традиционным для C и "неканонического" C++ способом перебора элементов массива, когда указателю присваивается адрес первого элемента и увеличивается до тех пор, пока не выйдет за пределы массива — как минимум, на адрес, следующий за последним элементом, но может выйти и дальше, если перебор не последовательный?


Если руки из жопы, то разве что отдать этот код тем, у кого они растут из правильного места.

ЕМ>Из каких соображений Вы заключаете, что вероятность именно такого поведения выше вероятности присутствия в коде скрытых ошибок, или ошибок компилятора, или ошибок системы, в которой будет работать код?


Здесь важна не вероятность, а зона ответственности. Ошибки в компиляторе или run-time библиотеке вне моей зоны ответственности. А вот написанный мной код -- в моей. И если мой код теряет работоспособность из-за моих ошибок, то отвечать за это мне.

Прецеденты того, как работавший в прошлом код перестал быть таковым из-за оптимизаций в очередной версии компилятора, уже были. Очень наивно предполагать, что подобного не может произойти в будущем.