LINUX.ORG.RU

Произошло очередное заседание комитета C++

 


0

4

25 июля произошло пленарное заседание комитета С++.

Были приняты последние возможности которые войдут в С++23.

Последующие заседания по С++23 будут лишь уточнять формулировки и готовить стандарт к сертификации ISO.

На cppreference уже обновили табличку: https://en.cppreference.com/w/cpp/23

Как вам новые добавленные возможности и что ждёте больше всего?

★★★★★
Ответ на: комментарий от fsb4000

Ну это потому что ты туда заведомо null передаёшь, и они это могут отследить.

Но на деле доступа тут не осуществляется и разыменования nullptr тут нет. Только подсчёт адреса.

По факту это эквивалент

struct usb_line6 *line6 = podhd + offsetof(struct usb_line6_podhd, line6);

И вся проблема в том, что компиляторы (как минимум кланг) воспринимают за ub адресные операции с nullptr, а не сам факт обращения к данным по адресу. https://gcc.godbolt.org/z/a4bPc1s6b

Ivan_qrt ★★★★★
()
Ответ на: комментарий от eao197

Тогда можно переформулировать и сказать, что это проблема не компилятора, а стандарта, т.к. считать вычисление адреса неопределённым поведением, как минимум странно. Доступ по адресу может быть неопределённым поведением, а сохранение адреса в переменную не должно быть таковым.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от Ivan_qrt

Я могу заблуждаться, но ведь не обязательно nullptr должен физически представляться значением 0. Это к 0 мы можем добавить некое смещение и получить осмысленное значение. А вот если nullptr – это, условно (uintptr_t)-42, то добавление к такому значению чего-либо не дает осмысленного результата. Поэтому и вычисление такого адреса не имеет смысла, как и сохранение результата подобного вычисления.

Кроме того, мне не понятен смысл этого разговора. Вот есть стандарт, международный, выдержавший несколько обновлений. В нем зафиксировано вот так.

Зачем эти стенания на LOR-е?

Если есть желание изменить стандарт, то https://stdcpp.ru/ и вперед.

Если нет желания, то пока что здесь вот так. И это вот так лучше учитывать, чтобы в один прекрасный момент программа не перестала работать будучи скомпилированной новой версией компилятора (или компилятором от другого производителя). Причем поведение компилятора будет полностью соответствовать стандарту.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

не обязательно nullptr должен физически представляться значением 0

Там скорей всего не в этом была проблема - а в агрессивных оптимизациях, которые лезут в поля.

chabapok
()
Ответ на: комментарий от eao197

ведь не обязательно nullptr должен физически представляться значением 0. Это к 0 мы можем добавить некое смещение и получить осмысленное значение.

Это значение не обязано быть осмысленным. Почему вообще на байтики в памяти накладывается требование осмысленности, если они не используются?

Зачем эти стенания на LOR-е?

Зачем вообще лор без стенаний на нём?

И это вот так лучше учитывать

Ну вот я лично по результатам этого треда преисполнился пониманием, что именно надо учитывать, за что тебе и @fsb4000 отдельное спасибо.

Менее странным стандарт от этого не становится, впрочем менять я его, конечно же, не буду.

Ivan_qrt ★★★★★
()
Ответ на: комментарий от fsb4000

Прикольно. Сравнил ради эксперимента с вот такой шляпой

struct usb_line6 *line6 = (usb_line6 *)(((char*)podhd) + 4);

gcc, код в результате тот же, но без UB :)

clang ругается «applying non-zero offset 4 to null pointer»

https://gcc.godbolt.org/z/d5YahP6c8

foxes
()
Ответ на: комментарий от Ivan_qrt

Тогда можно переформулировать и сказать, что это проблема не компилятора, а стандарта, т.к. считать вычисление адреса неопределённым поведением, как минимум странно. Доступ по адресу может быть неопределённым поведением, а сохранение адреса в переменную не должно быть таковым.

Нет никакой проблемы ни в стандарте, ни в компиляторах. &foo->bar означает «взять адрес поля bar структуры, на которую ссылается указатель foo». foo-> - это разыменование указателя. То, что в некоторых случаях компилятор делает это просто сложением - это оптимизация. Кстати, оптимизация возможная только от того, что разыменование nullptr - это UB и компилятору разрешено такой вариант не рассматривать. В некоторых случаях такая оптимизация невозможна, например если bar - это ссылка или если bar - поле виртуального базового класса. Тогда &foo->bar перестаёт делаться сложением и компилятор генерирует честное обращение к памяти и получение адреса.

khrundel ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.