LINUX.ORG.RU

Субботний C++ (как правильно сообщать о не успехе)

 


0

2

Продолжаю осваивать С++. И возник вопрос как сделать правильно следующую вещь…

Есть некий метод некоего объекта. Метод в случае успеха создает некий другой объект. Ну и естественно хочется возвращать его через return.

Но возможен другой ход развития событий, когда успеха не было. Это штатная ситуация. В си я бы похожую задачу решал бы посредством возвращения указателя на структуру. Либо указатель на созданную, либо null. Снаружи типа анализируем, и решаем что делать дальше.

А вот как такое правильно делать in cpp-way?

Все классы и методы мои, могу написать что захочу. А вот какие варианты идейно верные?

★★★

Ответ на: комментарий от aquadon
#pragma once

template <typename T>
struct Maybe {
  std::shared_ptr<T> xvalue;
  Maybe() {}
  Maybe(std::shared_ptr<T> value) : xvalue(value) {}
  operator bool() {return xvalue;}
  template <typename F>
  auto bind(F f) -> decltype (f(*xvalue)) {
    if (xvalue) {
      return f(*xvalue);
    } else {
      typedef X decltype (f(*xvalue));
      return Maybe<X> ();
    }
  }
};

template <typename T, typename F>
auto operator >>=(Maybe<T> m, F f) -> decltype(f(*m.xvalue)) {
  return m.bind(f);
}

парсер комбинаторы тоже можно. выглядить конечно вырвиглазно.

можно обобщить шаблонами ещё больше и сделать сборник ф-ий из control.monad. я пробовал, но получается треш и угар, не рекомендую.

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

Ну так он заоптимизурует, если там действительно данные по ptr есть (либо сам подставит).

Нет. Он заоптимизирует, потому что в стандарте написано, что при ptr==NULL возникает неопределённое поведение, а значит такой случай можно не рассматривать.

#include <iostream>
#include <string>

std::string f(int *p)
{
  int i = *p;

  if(p == NULL)
    return "null";

  return "not null";
}

int main()
{
  std::cout << f(NULL) << std::endl;
}

$ g++ null.cc -O2 -o null
$ ./null 
not null
hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от pavlick

Не станет. Комитетчики из C++ скорее себе вены в заднице вскроют и повесятся на собственных кишках, чем уберут UB из языка. Пиши на Rust.

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

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

i = ++i + 2;       // undefined behavior until C++11
i = i++ + 2;       // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i);       // undefined behavior until C++17, unspecified after C++17
i = ++i + i++;     // undefined behavior
cout << i << i++; // undefined behavior until C++17
a[i] = i++;       // undefined behavior until C++17
n = ++i + i;      // undefined behavior

А разрешить ноль дереференсить, да на производительности никто не заметит.

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

Потому что компилятору так захотелось. Неопределенное поведение. Ты читать-то умеешь, родное сердце?

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

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

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

Либо сишный путь (вот назовите мне кто-нибудь, чем он плох,

Если делать так как у топикстартера то тем, что требует лишнее выделение памяти на стеке, std::optional позволяет вернуть чисто стековый объект. Понятно что в си тоже можно сделать вариант с передачей ползовательского буфера но он менее удобный.
Еще даже с++ вариант с возвратом умного указателя лучше тем, что не нужно потом заботится об удалении результата.

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

Потому что компилятор реализует спеку языка, а не твои представления о языке, типа «он должен давать прочитать неинициализированную память».

Потому что компиляторщики стандарт знают, а ты нет.

Потому что оптимизации всем нужны, а быдлокод - не всем.

Потому что выкидывать невалидный код - правильно.

Каких умозаключений не хватает?

anonymous
()

А вот как такое правильно делать in cpp-way?

Нужно создать шаблонный класс, обязательно использовать паттерны и исключения. Даже если складывается 2 и 2. Это и есть cpp-way.

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

Потому что оптимизации всем нужны, а быдлокод - не всем.

Ну в части нулевых указателей - это просто тупость какая-то, а не оптимизация, ты ничего с них не выйграешь, все и так в норме проверяют указатель из потенциально нулаблельной функции, а разыменовать могут лишь по недосмотру. В чем резон не читать с нуля, когда таких мест и так быть не должно? Чего ты там выигрывать собрался? А это тоже свечь не стоит:

*ptr
if (!ptr) // сносим if

никто так не пишет, только по запарке. И компиляторостроители используют такие возможности чтобы тебя просто наказать, такое впечатление создаётся. Из всех возможных вариантов компилятор делает как можно хуже. Нет здесь смысл от таких дерьмооптимизаций.

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

Да.

не нашел. а вот в срр reference написано следующее казуистическое утверждение:

https://en.cppreference.com/w/cpp/language/ub

     Compilers are not required to diagnose undefined behavior (although many simple situations are diagnosed), and the compiled program is not required to do anything meaningful. 

UB and optimization

Because correct C++ programs are free of undefined behavior, compilers may produce unexpected results when a program that actually has UB is compiled with optimization enabled: 

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

То есть побороли уб непредсказуемой чушью. гениальный ход. возвращаясь к определению уб, что есть «чушь непредсказуемая» мы попадаем в какой-то логический парадокс это и написано в стандарте???

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

Не вы с павликом первые, не вы последние. Регулярно кому-то крутому «я с шести лет на асме ваяю» рвет шаблон, когда он узнает что все-таки написано в стандарте. В первых разделах, кстати, основы основ. Начиная с 89-го года.

Либо понять и принять, либо менять язык.

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

Ну, да. Всё так. Если у тебя в коде UB, программа может делать всё что угодно. Тебе об этом весь тред затирают анонимус и я.

Или ты думаешь, C и C++ просто так считают чудовищным говном?

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

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

Так в том и дело, что ты уже проверяешь (должен) и если компилятор ещё одну проверку начнёт вставлять (а если ты проверяешь где-то на верхнем уровне, а потом много раз используешь, то и не одну), то это будет «не зирокост».

И компиляторостроители используют такие возможности чтобы тебя просто наказать, такое впечатление создаётся.

Стадию отрицания ты уже прошёл. Осталось понять, что так делают не с целью лично тебе поднасрать, а что компилятор не может гарантированно сообщать о том, что случилось UB.

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

Ну, да. Всё так. Если у тебя UB, программа может делать всё что угодно. Тебе об этом весь тред затирают анонимус и я.

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

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

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

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

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

Нет, чувак, мы тебе затирали именно туда. Undefined behaviour – это буквально значит, что поведение программы не определено. То есть оно может быть любым. Вообще любым. Тут нет странного правила, тут вообще никакого правила нет.

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

И вот именно за это C и C++ все так любят :)

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

Так в том и дело, что ты уже проверяешь (должен) и если компилятор ещё одну проверку начнёт вставлять (а если ты проверяешь где-то на верхнем уровне, а потом много раз используешь, то и не одну), то это будет «не зирокост».

Согласен, это логично

Стадию отрицания ты уже прошёл. Осталось понять, что так делают не с целью лично тебе поднасрать, а что компилятор не может гарантированно сообщать о том, что случилось UB.

А вот с этим нет. И ты вряд ли объяснишь, ибо и сам вряд ли знаешь. Если вернуться к примеру, который был предоставлен

#include <iostream>
#include <string>

std::string f(int *p)
{
  int i = *p;

  if(p == NULL)
    return "null";

  return "not null";
}

int main()
{
  std::cout << f(NULL) << std::endl;
}

Это был не совсем честный тест и я пропустил одну деталь. Причина вывода «not null» в том, что i не используется, и компилятор это чтение просто вырезает (но в if’e этого не понимают, ведут себя так, буд-то оно было). А если компилить как и положено с флагом -Wall, то будет воринг «unused variable», после сноса или использования i где-нибудь, программа начнет падать как приличная. В итоге имеем нормальную работу с нулевыми указателями на ГЦЦ, и кривую срущую тебе под ноги шланговскую. Зачем вторые тебе делают больно, а первые нет - хз. Хотя формально ЮБ, но можно это использовать для тупых ничего не дающих оптимизаций, а можно нет.

В общем ни в чем вы меня ребята не убедили, я лишь понял, что шланг - кривое поделие.

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

Это был не совсем честный тест и я пропустил одну деталь.

Что в нём нечестного-то?

Причина вывода «not null» в том, что i не используется, и компилятор это чтение просто вырезает (но в if’e этого не понимают, ведут себя так, буд-то оно было).

Причина вывода «not null» в том, что поведение программы не определено из-за разыменования нулевого указателя. То есть может быть любым. Вообще. На этом можешь остановить свой поток рассуждений, потому что, например, завтра может выйти новая версия GCC или Clang, которая на такой код будет выдавать форматирование диска, если указатель равен NULL, и это всё ещё будет корректным поведением компилятора.

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

Причина вывода «not null» в том, что поведение программы не определено из-за разыменования нулевого указателя. То есть может быть любым. Вообще. На этом можешь остановить свой поток рассуждений, потому что, например, завтра может выйти новая версия GCC или Clang, которая на такой код будет выдавать форматирование диска, если указатель равен NULL, и это всё ещё будет корректным поведением компилятора.

Ой, ну вот этот вот бред про формат диска … ). ЮБ - почти всегда значит, что это отдано на откуп компилятору, он может оптимизировать, делать что хочет. Не, ну можно специально делать больно юзерам, как это делает шланг, а главное с такой оптимизации толку нет. Но лучше, конечно, прописать в стандарте - unspecified, чтобы шланг тоже начал делать так, как это наиболее приемлемо для программистов. Я это про обращение по нулевым указателям, нужно всегда читать память, а не пихать в регистры желаемый компилятором бред.

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

ЮБ - почти всегда значит, что это отдано на откуп компилятору, он может оптимизировать, делать что хочет.

Кто тебе такую лажу сказал? Ещё раз, для особо невнимательных повторю: термин undefined behaviour означает, что поведение программы не определено и может быть любым. Вообще совсем любым. Свои влажные фантазии оставь при себе.

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

Причина вывода «not null» в том, что поведение программы не определено из-за разыменования нулевого указателя. То есть может быть любым. Вообще.

любым быть не может. тетрис с разыменованием нулевого указателя не превратится в компилятор с++. тетрис этот просто свалится с вполне определенной диагностикой - access violation. о каком любом поведении идет речь?

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

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

Кто тебе такую лажу сказал? Ещё раз, для особо невнимательных повторю: термин undefined behaviour означает, что поведение программы не определено и может быть любым. Вообще совсем любым.

Оно не может быть любым. Это лишь значит, что оно не документируется, и может меняться спокойно с новой версией окружения. Не более того. Ты думаешь я специально нули дереференсю? Нет, это просто потенциальная ошибка, которую можно легко ловить, если не играться в тупые, ненужные оптимизации как делает это шланг.

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

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

Мне, похоже, стоит начать брать деньги за чтение стандарта другим людям.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

Страница 5, пункт 3.27:

undefined behavior
behavior for which this document imposes no requirements

Тебе перевести? :)

Ты думаешь я специально нули дереференсю?

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

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

Код, который выдаёт шланг, выполняется согласно тому, что написано в стандарте. Если твои ожидания отличаются, то это твоя проблема.

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

любым быть не может. тетрис с разыменованием нулевого указателя не превратится в компилятор с++. тетрис этот просто свалится с вполне определенной диагностикой - access violation. о каком любом поведении идет речь?

Охлолже! Ну вон я выше пример кода привёл, в котором разыменование NULL есть, а access violation нет. Более того, разные компиляторы выдают разный код. Где теперь твой бог?

и хватит отсылать к стандарту с++ там нет ни слова об оптимизации и выкидывании ветвей с уб

Ты же сам процитировал C++ Reference. Ну и вон я выше Павлику процитировал кусок стандарта про UB, где написано, что поведение может быть любым и ограничений на это нет.

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

А если найду?

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

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

Ненавистью. Разрабы компилятора тайно тебя ненавидят и выкидывают куски твоего кода при любой возможности. Ты вот потратил время, написал, протестировал (нет) и гордишься своей работой. А они это код вероломно выкинули.

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

Ты можешь поговорить об этом с компилятором, но он все равно выкинет твой код. Потому что ты его сучка. Куда ты денешься, на Rust писать пойдешь?

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

Ты думаешь я специально нули дереференсю? Нет, это просто потенциальная ошибка, которую можно легко ловить, если не играться в тупые, ненужные оптимизации как делает это шланг.

Компилятор этого не может знать. Вдруг ты пишешь «супер-оптимизированную» библиотеку, где каждый такт на счету, а входные данные (не нулевой ли указатель) проверяются один раз где-то выше (может даже не в этой библиотеке)? Откуда компилятору знать с какого уровня надо проверять?

Тут нет решения, кроме как проверять каждый раз, но на это сишники не пойдут под страхом смерти. Или вводить специальные типы для «ненулевых указателей». Ну или как сейчас: программист должен позаботиться о том, что неопределённого поведения нет.

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

И ты вряд ли объяснишь, ибо и сам вряд ли знаешь.

По моему, это очевидно. Кстати, были попытки сделать инструмент, который бы определял UB на основе того, что компилятор выбросил код. Могу представить, что в результате было множество ложных срабатываний. Ну и есть же UndefinedBehaviorSanitizer, но как и другие санитайзеры - это не часть компилятора.

В общем ни в чем вы меня ребята не убедили, я лишь понял, что шланг - кривое поделие.

Удачи в написании кода. (:

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

Почему? Им нравится страдать?

По всей видимости. Ну а ещё можно смеяться над языками, которые «тормозят».

Справедливости ради, вариант «всегда всё проверять» тоже не всегда работает.

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

Справедливости ради, вариант «всегда всё проверять» тоже не всегда работает.

Вариантов, как это решить, на самом деле тьма. Можно сделать отдельный тип для ненулевых указателей (не удивлюсь, если для C++ есть библиотека с этим, вот например: https://github.com/microsoft/GSL/blob/main/include/gsl/pointers). Можно сделать пару новых операторов, который при разыменовании кидают исключение если там NULL. Можно добавить прагму, которая включает проверки в каком-то отдельном участке кода.

Просто C/C++ и нормальные решения проблем – это абсолютно несовместимые вещи. C/C++ – это про то, как сделать через жопу, чтобы всем было максимально больно. Ей богу, ректальный копромазохизм от мира программирования.

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

Куда ты денешься, на Rust писать пойдешь?

нет конечно. я вообще проблемы не вижу тут..не следил правда за паралельной дискуссией. выкидывание кода и принудительное конструирование компилятором «правильных» функций…это не стандарт языка, а типичная переоптимизация, на основе ложных утверждений. хорошо бы, чтобы такое поведение отключалось каким-нить флагом, поскольку только маскирует ошибку. и хорошо бы, чтобы выкидывание кода изза уб сопровождалось варнингом.

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

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

нет конечно. я вообще проблемы не вижу тут..не следил правда за паралельной дискуссией. выкидывание кода и принудительное конструирование компилятором «правильных» функций…это не стандарт языка, а типичная переоптимизация, на основе ложных утверждений. хорошо бы, чтобы такое поведение отключалось каким-нить флагом, поскольку только маскирует ошибку. и хорошо бы, чтобы выкидывание кода изза уб сопровождалось варнингом.

Ты забыл, что авторы компилятора тебя ненавидят? Они никогда этот флаг не добавят.

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

Ты ведь в курсе, что невозможно написать функцию syscall() в том виде, в каком она есть, без UB? Если перестать компилировать программы с UB, то весь твой *NIX в тот же день перестанет работать :D

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

типичная переоптимизация отключалось каким-нить флагом маскирует ошибку это типичная ошибка ругаться

а ты упорный. наверное даже твердолобый.

хх другой анон

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

Ну так gsl::not_null - это и есть официально рекомендуемый путь на сегодня. Ты сам павлику уподобляешься, когда гонишь на язык.

Плюс, указатели вообще выбираются именно тогда когда нуль возможен, иначе ссылка. Тут, конечно, не хватает промежуточного типа - мутабельных ссылок, да оно по опыту нечасто надо, и тут и заходит not_null.

И вообще, плюсовых проблем встречал/делал достаточно, но чтоб разыменование нуля - это большая редкость. Разговоров больше.

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

Если перестать компилировать программы с UB, то весь твой *NIX в тот же день перестанет работать :D

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

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

Страница 5, пункт 3.27:

Еще раз - нет никакого «абсолютного» ЮБ, что вот поведение прям вообще пальцем в небо. Большая их часть - пространство компилятору для оптимизаций. Тут можно вспомнить про то, как MSVC не делает strict aliasing оптимизацию, делая ЮБ вполне определенными в рамках себя. Да и в том же ГЦЦ можно включать оптимизации поштучно. Понятно, что есть вещи, которые от компилятора не зависят, ALSR, например.

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

Ну маскируй ошибки, успехов могу лишь пожелать. А я лучше эту ошибку найду при помощи нормального компилятора без дерьмооптимизаций и исправлю, а твой код на ЮБ будет работать т.к. шланг выплюнул каку-то непотребную какашку (хоть она и малость быстрее, да) и хрен ты его обнаружишь, ибо шибко ЮБ-эксперт.

char f(int i) {
	if (i == 1)
		return *(char*)0;
	return 'f';
}

-O3 шланг:
        movb    $102, %al
        retq

-O3 ГЦЦ:
        cmpl    $1, %edi
        je      .L4
        movl    $102, %eax
        ret
.L4:
        movzbl  0, %eax
        ud2

Скорее всего поведение обоих компиляторов можно подтюнить флагами оптимизации на противоположное. Но ГЦЦ поступает много умнее - дефолтно выбирает более надежный вариант, а особые гурманы доведут производительность до предела.

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

Вариантов, как это решить, на самом деле тьма. Можно сделать отдельный тип для ненулевых указателей (не удивлюсь, если для C++ есть библиотека с этим, вот например: https://github.com/microsoft/GSL/blob/main/include/gsl/pointers). Можно сделать пару новых операторов, который при разыменовании кидают исключение если там NULL. Можно добавить прагму, которая включает проверки в каком-то отдельном участке кода.

Жесть, велосипедист. Все есть и работает, тебе твои ЮБ шоры мешают.

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

Павлик, советую вам погуглить unspecified.

Владимир

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

Еще раз - нет никакого «абсолютного» ЮБ, что вот поведение прям вообще пальцем в небо

Это ты на простых примерах можешь так считать. А теперь сходи разберись, почему в проекте 20-летней давности на 500к строк что-то так почему-то неправильно выполняется.

Тут можно вспомнить про то, как MSVC не делает strict aliasing оптимизацию, делая ЮБ вполне определенными в рамках себя.

Потому что программисты на C не могут в strict aliasing в большинстве случаев. Большая часть линуксокода перестаёт работать, если его включить.

А я лучше эту ошибку найду при помощи нормального компилятора без дерьмооптимизаций и исправлю, а твой код на ЮБ будет работать т.к. шланг выплюнул каку-то непотребную какашку (хоть она и малость быстрее, да) и хрен ты его обнаружишь, ибо шибко ЮБ-эксперт.

$ cat null1.cc 
#include <iostream>

char f(int i) {
  if (i == 1)
    return *(char*)0;
  return 'f';
}

int main()
{
  std::cout << f(1) << std::endl;
}

$ clang++ null1.cc -o null -O2 -fsanitize=undefined
null1.cc:5:12: warning: indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]
    return *(char*)0;
           ^~~~~~~~~
null1.cc:5:12: note: consider using __builtin_trap() or qualifying pointer with 'volatile'
1 warning generated.

$ ./null 
null1.cc:5:12: runtime error: load of null pointer of type 'char'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior null1.cc:5:12 in 
f

Ах какой же шланг нехороший!

Но ГЦЦ поступает много умнее - дефолтно выбирает более надежный вариант, а особые гурманы доведут производительность до предела.

Ты реально упорный в отстаивании своего желания говнокодить.

Жесть, велосипедист. Все есть и работает, тебе твои ЮБ шоры мешают.

У тебя вот не работает :D

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

Ах какой шланг

Тьфу ты … Вы бы хоть погуглили для начала …

Владимир

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

indirection of non-volatile null pointer will be deleted, not trap [-Wnull-dereference]

да вот же флаг о котором я говорил пару постов назад! что он быть должен. и вразумительная диагностика - кусок будет удален.

и чего копья ломать? ответ на вопрос - …зачем его вообще удалять, остается на совести удаляющих…

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

Ладно, я все. Мнениями обменялись. Я никого не призываю на ЮБ писать, наооборот - предлагал избавляться от него используя нормальный компилятор без этих зашкварных оптимизаций (да шлангу тоже можно отключить 100%, но зря он так дефолтно на -O>0 делает, имхо).

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

Я никого не призываю на ЮБ писать, наооборот - предлагал избавляться от него используя нормальный компилятор без этих зашкварных оптимизаций (да шлангу тоже можно отключить 100%, но зря он так дефолтно на -O>0 делает, имхо).

Да, но зачем такой компилятор будет нужен? Программисты на C++ должны страдать по максимуму.

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

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

Да ты можешь отвергать что угодно. Реальность от этого не изменится.

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

Ты написал быдлокод не по стандарту, компилятор насовал тебе за обе щеки, кончил на футболку и вытер член о занавески. Всё честно, это C.

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

Ты написал быдлокод не по стандарту

а ты написал быдлокоммент, как бУдто ты с++ компилятор. ты может с ума сошел, не?

Это анонимус. Учитывая сложность и количество кода в компиляторах C++, я не удивлюсь, если один из них наконец-то обрёл сознание и пишет на ЛОР. А, быть может, даже модерирует его!

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

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

или компилятором твоего любимого языка.

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

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

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