Вот, в ECMAScript 2015 с аналогичным кривым использованием переменных бороться пытались - и ввели let и const... А тут - прямо компилятором по стеку! Агрессивно!
Массивы констант используются через указатель после выхода из блока кода, в котором они объявлены? :о))) За такое убивать надо! Причём и кодера, который такое пишет и тех, кто такой компилятор накосолапил, который такое пропускает.
![[User Picture]](https://l-userpic.livejournal.com/42563024/889305) | From: dzz 2018-05-03 12:03 pm
| (Link)
|
Принципиально, что не просто указатель, а на стек.
![[User Picture]](https://l-userpic.livejournal.com/42563024/889305) | From: dzz 2018-05-03 12:01 pm
| (Link)
|
Что характерно, компилятор совершенно прав :) Напоминает ситуацию с правоприменением, когда начинает энфорситься какой-то давно принятый закон, на который раньше просто забивали. Вроде, всё по правилам, но неуютно, в данном случае - для неаккуратного кода.
Вот сегодня как раз такой баг правил, с указателем на локальную переменную. Только там не было выхода из блока, зато был рекурсивный вызов.
![[User Picture]](https://l-userpic.livejournal.com/7623932/156202) | From: pargentum 2018-05-03 12:16 pm
Вообще-то статья расстрельная | (Link)
|
А на неделе хозяйка велела вернуть буфер из служебной функции, а я объявил локальный массив внутри функции и на него указатель вернул. А она взяла стэк с мусором и начала моей харей по ему водить...
![[User Picture]](https://l-userpic.livejournal.com/81048954/111931) | From: avva 2018-05-03 03:21 pm
Re: Вообще-то статья расстрельная | (Link)
|
Смешно, но это не тот случай.
воссоздать = воспроизвести
А какого хрена компилятор не выдал предупреждение ?! Или читать вывод компилера не метод суровых профи? :) Я тупо сейчас проверил свой GCC на такой кейс: "warning: address of local variable 'xxxx' returned [-Wreturn-local-addr]"
Насколько я понял, там было не returned, а передавалось в функцию, которая (надо понимать) запоминала указатель.
gl_->UniformMatrix3fv(yuv_matrix_loc_, 1, 0, yuv_matrix); gl_->Uniform3fv(yuv_adjust_loc_, 1, yuv_adjust);
Причем он от рождения был хром. (Правда, сейчас это принято называть "альтернативный браузер".)
Прекрасный баг?!!! Это ж детский сад просто, выдавать наружу указатель на переменные на стеке.
From: (Anonymous) 2018-05-03 01:48 pm
| (Link)
|
"Решение" в виде static унутре блока тоже порадовало.
И что, вся наша цивилизация основана вот на таких кривых, кустарных алгоритмах? Какой ужас. Пора уже, товарищи программисты, выходить на какой-то новый уровень качества. А то ведь ненароком все передохнем.
За здоровую ретроградчину! Долой новые версии компиляторов!
PVSStudio вроде бы находил этот баг статическим анализом в хромиуме.
PVSники уже много лет публикуют статьи о проверке хромиума и все сокрушаются, что до сих пор нет покупки. Если баг действительно находили, то самое время для новой статьи "а мы же говорили".
From: (Anonymous) 2018-05-03 02:08 pm
| (Link)
|
utter waste of time valgrind is your friend address sanitizer is your friend ub sanitizer is your friend
Это все, подозреваю, тулзы продлевающие патриархальные стереотипы. Когда люди начинают бороться за гендерное выравнивание команд, то им не до них.
а кланг-чек такое разве не ловит?
From: (Anonymous) 2018-05-03 02:51 pm
| (Link)
|
нет, вроде не ловит.
From: (Anonymous) 2018-05-03 02:43 pm
| (Link)
|
Для особо любознательных, баг там был примерно такой:
void buggy_function() { float* table = nullptr; if (some_condition) { float another_table[] = { 0.1, 0.2, 0,3 }; table = another_table; } some_other_function(table); }
Да. И проблема не в том, как подумали некоторые, что some_other_function запоминает значение table где-то и позже оно используется после выхода из функции.
Проблема в том, что другие локальные переменные, перед вызовом some_other_function(), расположены в том же месте стека, что another_table, и меняют часть ее значений, в результате чего some_other_function получает частично коррумпированную таблицу.
From: (Anonymous) 2018-05-03 03:12 pm
| (Link)
|
Ну, тут все-таки баг был, хоть и не проявлялся. У меня как-то было интереснее: баг, который в код никто не вносил. Просто после перехода с LinuxThreads на NPTL в legacy коде появились race conditions из-за того, что getpid() стала возвращать не thread ID, как раньше, а process ID. |