LINUX.ORG.RU

Ссылка по *nullptr?

 ,


0

2

У меня есть некая функция возвращающая ссылку. В некоторых случаях она должна вернуть заведомо невалидную ссылку и это должно легко проверятся тем кто ее вызывал, как то так

T& f(...){
   ...
   return *(T*)nullptr; 
   ...
};

Это немножко странно выглядит, но работает. Но на gcc8.3.0 уже не работает

T& ref = f(...);
if(&ref){...} //<== warning: nonnull argument ‘ref’ compared to NULL

насколько я понял он при оптимизации с -O3 эту проверку выкинул, а потом улетел с сегфолтом, дооптимизировался… gcc5.4.0 нормально работает.

В общем я готов поменять ссылку на указатель (хотя это слегка испоганит кое че дальше), но скажите - а с чего это вообще отвалилось то и насколько такая нулевая ссылка плоха? Ссылка же семантически ничем от указателя не отличается…

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

В том самом basic.compound читаю:

Не в том самом. Как сказал бы царь — твоя методичка протухла. Текущий стандарт это C++17, его финальный драфт это n4659. Впрочем, можешь посмотреть финальный драфт C++20 — n4861

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

Что такое объект который не в памяти?

Очевидно, объект который где-то еще (на регистре) или нигде (пустой объект).

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

А котечка то чем поможет, он лечит UB по аккаунту на лоре?

abcq ★★
()

Раз пошла такая пьянка.

Ссылка же семантически ничем от указателя не отличается

Разница в допустимых операциях на ссылкой и указателем. Условно ссылка - подмножество указателей.

Ссылка. Присвоить (ссылку), доступ (к объекту).

Указатель. Присвоить (указатель); доступ; получить следующий/предыдущий - семантика последовательного двустороннего итератора; которая может перерасти в полноценную арифметику указателей с умножениями и делениями.

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

Ну блин, аж бомбит. Они в C++17 реально поменяли семантику указателей (они теперь, походу, не особо отличаются от ссылок), вдобавок поменяли правила вычисления выражений, еще что-то там на тему динамических объектов (std::launder и т. п.).

Короче, поменяли фундамент языка, а это мало кто заметил - мол, минорщина ваш C++17.

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

полноценную арифметику указателей с умножениями и делениями

Откуда в арифметике указателей умножения и деления? [expr.mul] не упоминает указатели.

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

Они в C++17 реально поменяли семантику указателей

На самом деле не особо. Такая семантика подразумевалась и раньше.

В [basic.life] всегда были правила про то, когда существующий указатель начинает (или не начинает) указывать на новый объект после создания нового объекта поверх другого объекта (на который этот указатель указывал). Если значение указателя это просто адрес — то что значит, что он либо указывает на новый объект созданный по тому же адресу, либо продолжает указывать на старый? Очевидно, что под значением указателя в [basic.life] понимался не столько адрес, сколько… эмм… object identity.

В C++17 просто убрали неконсистентность между тем, что в стандарте неявно понималось под значениями указателя и тем как они определены в [basic.compound].

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

Откуда в арифметике указателей умножения и деления?

Ты решил придраться к допущению «может перерасти»?

ptr + ptr = ptr * 2

Как задашь бинарную операцию (оператор умножения), такая и будет (или не будет) «арифметика».

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

ptr + ptr

Складывать указатели нельзя. См. [expr.add] (For addition, either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.)

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

Складывать указатели нельзя.

Продолжаешь спорить с допущением «может перерасти». Ты же понимаешь, что можно легко сделать такую «арифметику» над указателями. Если есть операция сложения с опредленными свойствами (группа по модулю), то как не заметай мусор под ковер, всё равно вылезет.

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

А ptr - ptr = ptr / 2? Лол.

Можешь же, если захочешь. Продолжай.

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

Продолжаешь спорить с допущением «может перерасти». Ты же понимаешь, что можно легко сделать такую «арифметику» над указателями.

Когда сделают тогда и приходи. А пока хватит всякий бред сюда писать.

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

Когда сделают тогда и приходи.

Так это изначально было, как наследие си, как пример ptr[i] = i[ptr] = *(p+i). Это щас пытаются заметать под ковер, введя всякие новые «ограничения».

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

Если есть операция сложения с опредленными свойствами (группа по модулю)

Покажи эту операцию.

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

Видимо, так. Но как же это далеко от начальной идеи.

К слову. Это только у меня ощущение, что ссылки – костыль, толком не вписавшийся в язык? Сплошные исключения и ограничения. И они должны были быть чем-то вроде std::reference_wrapper (который и появился из-за их ограничений).

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

группа по модулю Покажи эту операцию.

Существование (U)INTPTR_MAX намекает.

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

Адрес памяти, и всё. K&R C, макроассемблер, никаких наворотов.

anonymous
()
Ответ на: комментарий от invy

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

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

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

anonymous
()

Скоро сам тред станет как undefined behaviour

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

Наверное. Но старого пса новым трюкам не научишь, мне как то обычные указатели и ссылки понятней.

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

Я долго игнорировал ваши угрозы заигнорировать пользователей форума, но больше не могу это игнорировать. Если вы и дальше продолжите игнорировать призывы перестать угрожать заигнорировать, я не смогу это игнорировать и буду вынужден проигнорировать игнорирование ваших угроз заигнорировать неопределённый круг лиц и всё-таки вас заигнорировать.

i-rinat ★★★★★
()

Ссылка же семантически ничем от указателя не отличается…

Отличается. Нулевая ссылка - UB.

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

да анон, когда возвращантся указатель, то не ясно что с ним можно делать и кто отвечает за память. еще не ясно сколько он остается валидным. а когда optional reference wrapper - всё понятно.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

В старом cpp может и не ясно, в современном - сырой указатель всегда observer, точно как и ссылка, только еще и nullable. Саттер уж мозоли набил это объяснять, в треде ссылки есть. Там же и про optional.

Это из той же серии что и std::observer_ptr, на который Страуструп сказал: «Ребята, не страдайте фигней, T* хватит всем». Вам лишь бы усложнить.

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

расскажи это авторам библиотек :)

по опыту: видишь указатель - лезешь в доку или код разбираться, что происходит внутри.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.