LINUX.ORG.RU

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

 


0

2

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

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

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

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

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

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

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

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

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

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

То ли дело C – вышел за границу массива и написал новую программу. Прямо в рантайме.

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

Ввести для возвращаемых объектов общего предка, например позволяющего проверить его состояние

Ну т.е. NULL да?

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

Но ты можешь попытаться доказать обратное.

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

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

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

Я понимаю что у тебя уже истерика начинается от осознания глубины своей профессиональной деградации, но все-таки попытайся понять одну простую вещь. Компилятор волен делать любые ассампшоны относительно UB. И он их будет делать. Просто чтобы тебя позлить.Ты будешь открывать все новые и новые способы как компилятор может тебя нагнуть и выкинуть твой код, уйти в бесконечный цикл или вызвать ОМОН чтобы выкопать труп твоей покойной бабушки и хорошенько его обоссать.

Ты, рыдая, будешь скулить на ЛОРе про флажки, способные избавить тебя от гнева компилятора, а адекватные форумчане будут крутить пальцем у виска. От тебя уйдёт жена, а твои дети будут проклинать тебя за позор, который лёг на ваш род

Подумай, нужно ли это тебе?

anonymous
()

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

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

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

Или я что-то не понял или все таки не clang, а gcc «кривое поделие» у меня именно gcc 10 выводит «not null», а clang 11 «null».

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

там за-за неспользуемой переменной косяк, ГЦЦ обращение в память выерезает, а до оптимизации с уалением повтороной проверки нулевого указателя (-fdelete-null-pointer-checks) эта инфа не доходит, в итоге и приложение не заваливается из-за исключения, и if вырезается. Ну да, ГЦЦ немного косячит.

Но к шлангу претензия другая - когда он в состоянии отследить ноль в каком-нибудь указателе и уровень оптимизации выше -O0, то он не читает из памяти по нулю, соответсвенно программа не падает. Тут можно порассуждать о ценности такой оптимизации (по-моему, она околонулевая), а вот обнаружение ошибок в коде это может значительно усложнить. Я бы предпочел включать (и то не факт) такое отдельно на уже отшлифованном коде. ГЦЦ таким даже на -Ofast не занимается.

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

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

Кстати, любителям порассуждать о ЮБ, о том, что это всегда небо на головоу и форматирование диска вместе с перегоранием ЦПУ и ГПУ вследствие интенсивного майнинга (из man gcc):

-fdelete-null-pointer-checks
Assume that programs cannot safely dereference null pointers, and that no code or data element resides at address zero. This option enables simple constant folding optimizations at all optimization levels. In addition, other optimization passes in GCC use this flag to control global dataflow analyses that eliminate useless checks for null pointers; these assume that a memory access to address zero always results in a trap, so that if a pointer is checked after it has already been dereferenced, it cannot be null.
Note however that in some environments this assumption is not true. Use -fno-delete-null-pointer-checks to disable this optimization for programs that depend on that behavior.

Что? Какие-то гарантии поверх ЮБ? В частности - these assume that a memory access to address zero always results in a trap. И - programs that depend on that behavior.

Берегите свои шаблоны.

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

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

Откуда такая любовь к говнокодерству, чувак? Не надо так делать. Надо код с UBSan на тестирование пускать и пользоваться статическим анализом. Ну, хотя бы от Лысого.

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

Ты щас пытаешься прикрыть тот факт, что, встретив UB, компилятор тихо меняет структуру программы, часто генеря невменяемую дичь, тем, что в GCC флажки есть? Серьёзно?

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

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

#include <iostream>

const char *i = "jkjjk";

bool request_to_device_and_return_success()
{
	char in;
	std::cin >> in;
	return in == 'f' ? false : true;
}

int main()
{
	if (request_to_device_and_return_success())
		i = nullptr;
	//if (i) // забыл написать if
	std::cout << *i << std::endl;
	return 0;
}

Конечно, наверняка есть анализаторы, которые помогут. И ты всё тестами покрываешь с ног до головы. А мне спокойней выкинуть на свалку одну паршивую оптимизацию. Хотя справедливости ради отмечу - проблему здесь находит clang-tidy, но х.з., возможно немного шаблонной магии и ничего не найдется, все же аппартное исключение надежней.

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

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

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

А компилятор хочет оптимизировать код, считая, что твоя программа следует стандарту. В этом-то и проблема C.

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

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

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

gcc делает массу таких оптимизаций, алё. Тебе выше показывали баг в кернеле.

Хочешь терпимости к говнокодерам - добро пожаловать на MSVC, и то не факт.

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

А компилятор хочет оптимизировать код, считая, что твоя программа следует стандарту. В этом-то и проблема C.

это все равно, что если у клиента при логине не совпадает пароль с реальным, на одну-две-три буквы, то система ему этот пароль подправит, и пропустит. Исходя из принципа, что пароль должен быть правильным всегда. Этот принцип есть? Есть. Очевидно, что принцип «корректности пароля» в данном случае толкуется неверно, и такое толкование способствует несанкционированному доступу. А раз оно способствует такому доступу, значит это неверное толкование.

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

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

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

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

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

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

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

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

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