LINUX.ORG.RU

Чудесный код С++

 


0

2

Хотите поржать?

BOOL ShaderElement::equal(ShaderElement* S)
{
    if (nullptr == S && nullptr == this)
        return TRUE;
    if (nullptr == S || nullptr == this)
        return FALSE;
    return equal(*S);
}
Как вы думаете, для чего оно?

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

★★★★★

Последнее исправление: eagleivg (всего исправлений: 2)

Для… сравнения?

Deleted
()

Был готовый метод BOOL ShaderElement::equal(const ShaderElement &S), к нему в пару решили сделать метод BOOL ShaderElement::equal(ShaderElement* S). Реализующий боялся, что если S == nullptr, произойдёт разыменование nullptr в *S, поэтому добавил проверок. Ещё он не знал, что this никогда не бывает равно nullptr, поэтому заморочился ещё и этим вариантом.

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

Ещё он не знал, что this никогда не бывает равно nullptr

Я просто оставлю это здесь: https://ideone.com/ePI6dO. И да, я знаю, что это UB.

Gvidon ★★★★
()
Ответ на: комментарий от i-rinat

Юмор в том, что как раз знал. Под линуксом падает чуть дальше, в том самом вызове equal(*S) и в отладчике видно, что this=0. https://cdn.discordapp.com/attachments/410452181213249546/497388465382621224/...
А под виндой работает.

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

Под линуксом падает чуть дальше, в том самом вызове equal(*S) и в отладчике видно, что this=0

Порча памяти?

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

Да.

Invalid read of size 1
  в ShaderElement::equal(ShaderElement&) в /home/builder/xray-16/src/Layers/xrRender/Shader.cpp:95
Address 0x8 is not stack'd, malloc'd or (recently) free'd  1: ShaderElement::equal(ShaderElement&) в /home/builder/xray-16/src/Layers/xrRender/Shader.cpp:95
  2: Shader::equal(Shader&) в /home/builder/xray-16/src/Layers/xrRender/Shader.cpp:125
  3: CResourceManager::_lua_Create(char const*, char const*) в /home/builder/xray-16/src/Layers/xrRenderPC_GL/glResourceManager_Scripting.cpp:521
  4: resptrcode_shader::create(char const*, char const*, char const*, char const*) в /home/builder/xray-16/src/Layers/xrRender/Shader.cpp:21
  5: CPSLibrary::Load(char const*) в /home/builder/xray-16/src/Layers/xrRender/PSLibrary.cpp:259
  6: CPSLibrary::OnCreate() в /home/builder/xray-16/src/Layers/xrRender/PSLibrary.cpp:28
  7: CRender::create() в /home/builder/xray-16/src/Layers/xrRenderPC_GL/rgl.cpp:358
  8: D3DXRenderBase::OnDeviceCreate(char const*) в /home/builder/xray-16/src/Layers/xrRender/r__dsgraph_build.cpp:895
  9: CRenderDevice::Create() в /home/builder/xray-16/src/xrEngine/Device_create.cpp:71
  10: Startup() в /home/builder/xray-16/src/xrEngine/main.cpp:196
  11: RunApplication() в /home/builder/xray-16/src/xrEngine/main.cpp:295
  12: entry_point(char const*) в /home/builder/xray-16/src/xr_3da/entry_point.cpp:45
  13: main в /home/builder/xray-16/src/xr_3da/entry_point.cpp:100
Но способ починки...

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

Ну, рукожопие — один из самых распространённых недугов, которые можно встретить в разработке :)

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

Deleted
()

Удалять нулевые объекты можно, так почему бы не разрешить их сравнивать? В легаси то, где уже никто не знает когда и откуда оно приходит, а надо в продакшон вчера и так что бы ничего не отломать.

Кстати я видел такой код (с проверкой на нуль в деструкторе), который и под gcc вполне себе работал. Или в деструкторе не UB?

onhydro
()

Дай угадаю - на самом высоком уровне ловятся все seh, и стоит catch(...)?

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

pon4ik ★★★★★
()
Ответ на: комментарий от i-rinat

C++ ликбез:

1) this может быть null

2) ссылка (референс) тоже может быть null

3) жизнь — боль

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

А это как так вышло? D3D под онтопик есть?


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

eagleivg ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Ещё он не знал, что this никогда не бывает равно nullptr

Сэр не видел MSVS и clang-а
не бывает)))) угу какже

перваяже лямбда(сложнее хело ворда) такой ад устроит с nullptr, никаких проверок не хватит

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

не бывает

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

Поэтому — не бывает. Если в коде где-то this оказался равным nullptr, нужно фиксить код, потому что одна заплатка проблем не решит.

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

Поэтому — не бывает. Если в коде где-то this оказался равным nullptr, нужно фиксить код, потому что одна заплатка проблем не решит.

фиксить код на каждое минорное обновление clang-а?

ес че, в clang будет ад и ужас с UB, если у тебя лямбда 1000-го уровня вызывает this->, вызывает его из «другого контекста»(класса) и объект this не глобальный

я уже писал не раз даже на лоре об этой «фиче» clang
эта фича делает рандомный результат с каждой новой версией clang

с msvs тоже самое, в пределах одной версии MSVS

единственный вариант-полностью отказаться от всех фич C++11

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

будет ад и ужас с UB, если у тебя лямбда 1000-го уровня вызывает this->

единственный вариант-полностью отказаться от всех фич C++11

Я так понимаю, не писать лямбду 1000-го уровня — не вариант?

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

Я так понимаю, не писать лямбду 1000-го уровня — не вариант?

не писать цикл с 1000+ проходами
не делать рекурсию 1000+
не делать while(true)
на что ты еще готов ради компилятора?

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

на что ты еще готов ради компилятора?

Я готов не передёргивать свои аргументы. А ты?

Deleted
()
Последнее исправление: ecko (всего исправлений: 1)

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

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

Пример давай. Наверняка у тебя адок с UB там.

i-rinat ★★★★★
()

Как вы думаете, для чего оно?

Грязный хак чтобы починить неизвестно где возникший UB или битую память?

former_anonymous ★★★
()

Тоже посмотрел на сталкера и испугался такого. Как поучаствовать? Wine используете? Пробовали с помощью clang в режиме совместимости под виндой собирать? Используете dr.memory?

xor2003
()

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

Valman_old
()
Ответ на: комментарий от i-rinat

Почему? setrlimit(RLIMIT_STACK,(const rlimit[]){{RLIM_INFINITY,RLIM_INFINITY}});

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

Если в коде где-то this оказался равным nullptr, нужно фиксить код

Не парься. Сколько я раз замечал — у них в плюсах бывает всё что угодно. А потом над пыхом ржут, в котором тоже бывает всё что угодно. Но ведь дело не в бобине...

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

единственный вариант-полностью отказаться от всех фич C++11

Но очень не хочется, да?

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

не писать цикл с 1000+ проходами
не делать рекурсию 1000+
не делать while(true)

Чорт, не ожидал ))

deep-purple ★★★★★
()

Кстати, еще разит тотальное отсуствие const

KennyMinigun ★★★★★
()

rust все равно не взлетит

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

https://github.com/q4a/xray-16/ - там есть ссылка на diskord канал. Из wine таскаем некоторые енумы, силангом пробовали, собирается, dr.memory пробовал, не впечатлил по сравнению с valgrind.

eagleivg ★★★★★
() автор топика

потому что патлатое чудо решило не проверять на null при вызове метода объекта. а это 2 (две карл) ассемблерные инструкции.

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

если у тебя лямбда 1000-го уровня вызывает this->, вызывает его из «другого контекста»(класса) и объект this не глобальный

это называется кривые руки. язык программирования тут ни при чём.

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

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

Вуаля

s/В/Ф/ s/a/б/

А вообще, UB: https://wandbox.org/permlink/iI9WNLsG6JgUAcRc

UB == место для оптимизции для компилятора, и, например, с очередным обновлением вместо nullptr в this окажется какой-то мусор (или указатель на другой обьект).

Т.е. я понимаю, что ты лишь хотел показать, что такое возможно. Но речь о том, что такое нельзя делать (в значении «лучше не делать»).

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

Я так понимаю, примера мы не дождёмся?

Помогите разобраться, это баг LLVM или нет

GLSL демка/игра (играть онлайн) (комментарий)

также еще одни бинарники можно тут смотреть https://github.com/danilw/small-2d-game

баг только в clang, только при сборке не на x86_64
у меня есть MIPS и PPCпроцессоры, на которых я собирал для теста gcc-никаких утечек памяти и лямбды не исчезают
clang-ом собрал помимо wasm, только для MIPS(все очень плохо, сегфаулт на старте вообще)

по прежнему- возможно таки баг и у меня в коде/коде либы, но факт сборки без багов под x86_64 остается фактом

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