? ?
 

gcc

About Уничтожить всех уродов

Previous Entry gcc 2 янв, 2017 @ 19:24 Next Entry
для меня стало большим откровением, что ежели у вас аргументы сишной функции сами есть результаты вызовов функций - типа так:
foo (i, bar(i,&j), j);
и при этом (как в примере выше) один из этих вызовов на лету возвращает, через указатель, НОВОЕ значение какой-то там переменной j, которую вы чуть позже передаёте аргументом,.. то на самом деле вовсе не обязательно, что функция foo получит это НОВОЕ значение j. Оно запросто может оказаться предыдущим, потому что программист идиот, а компилятор умный.

если же сделать так:
k = bar(i,&j);
foo (i, k, j);

то всё хорошо
Оставить комментарий
(Удалённый комментарий)
[User Picture Icon]
From:kincajou
Date:Январь, 2, 2017 17:09 (UTC)
(Link)
возможно, что баг, но какой-то он слишком простой. Скорее, это я чего-то не понимаю.

А всё потому, что пишу лучший в мире контроллер для лучшей в мире матричной клавиатуры, отрабатывающей сколько угодно одновременных нажатий без эффекта .. ээ.. как это по-русски-то, когда три нажатьых кнопки создают иллюзию, словно ещё четвёртая нажата. Схемотехнически - понадобилось на каждую кнопку добавить диод. Программно - понадобился FIFO, чтобы хранить все нажатия-отпускания, пока их центральный контроллер не считает
[User Picture Icon]
From:redddis
Date:Январь, 2, 2017 22:13 (UTC)
(Link)
а антидребезг аппаратный?
[User Picture Icon]
From:kincajou
Date:Январь, 3, 2017 01:54 (UTC)
(Link)
простейший RC против совсем уж высокочастотных наводок.
Сначала устанавливается сканирующий уровень на столбец, затем, через офигительный промежуток времени в десяток или около того миллисекунд читается строка (или наоборот, уже не помню). Дребезг.. фиг с ним, пусть даже есть - либо нажатие клавиши будет поймано и пропущено через алгоритм типа "нажата..шлём код кнопки... всё ещё нажата... всё ещё нажата.. шлём код повтора..шлём код повтора.. о, оптущена! шлём код отпускания!". Дребезг совершенно не важен, главное чтоб ЛОЖНЫХ нажатий не было.
[User Picture Icon]
From:kincajou
Date:Январь, 2, 2017 17:11 (UTC)
(Link)
эффект есть и на х86, и на ARM.. так что, наверное, это что-то глубинное.
[User Picture Icon]
From:metaclass
Date:Январь, 2, 2017 19:38 (UTC)
(Link)
Нет, по стандарту порядок вычисления аргументов функции - unspecified, т.е. компилятор может их вычислять в любом порядке.
[User Picture Icon]
From:oppositus
Date:Январь, 2, 2017 16:48 (UTC)
(Link)
1. Не используй это говно (С++)
2. Просто не используй это говно (С++)!
3. Если нужен С-лайк езыг, ну так есть же С! А С++ говно.
[User Picture Icon]
From:kincajou
Date:Январь, 2, 2017 17:10 (UTC)
(Link)
что за C! ? Си-факториал? ;)
[User Picture Icon]
From:gorrah
Date:Январь, 2, 2017 18:03 (UTC)
(Link)
//Если нужен С-лайк езыг, ну так есть же С! А С++ говно.

А куда деться? Ведь его много и оно повсюду.
[User Picture Icon]
From:oppositus
Date:Январь, 2, 2017 18:27 (UTC)
(Link)
Ядро Линукса смогли таки написать на С. Вот и всё остальное можно. Достаточно проявить твёрдость - послать сипипирпсов на 3 буквы, например...
[User Picture Icon]
From:bulygin_roman
Date:Январь, 2, 2017 17:34 (UTC)
(Link)
Эк умело-то Вы себе грабельки разложили. Не надо так. Си он недалеко от ассемблера ушёл и при том способов отрезать себе яйца только преумножил. А просходит то, что порядок вычисления параметров функции в общем случае не определён , определяется компилятором.
http://ru.cppreference.com/w/cpp/language/eval_order
[User Picture Icon]
From:Шура Люберецкий [luberetsky.ru]
Date:Январь, 2, 2017 17:44 (UTC)
(Link)
А кто сказал, что аргументы foo будут вычисляться именно в том порядке, в каком записаны? Порядок вычисления аргументов - это типичный пример unspecified behaviour.
[User Picture Icon]
From:kincajou
Date:Январь, 2, 2017 18:14 (UTC)
(Link)
ну да, да, это я уже понял. Просто в лиспе оно чётко оговорено - аргументы функции вычисляются справа налево. Я и подумал, что раз в древнем языке так, то в более новых уж тем более так!

Edited at 2017-01-02 18:14 (UTC)
[User Picture Icon]
From:Шура Люберецкий [luberetsky.ru]
Date:Январь, 3, 2017 11:00 (UTC)
(Link)
В Си порядок вычислений оговорен строго в одном месте - аргументы || и && вычисляются слева направо, а сами эти операторы лево- или право- ассоциативны, то есть a || b || c вычисляется, как (a || b) || c, либо как a || (b || c) - в любом случае сначала будет вычислено a, потом b, потом c. Это просто удобно в конструкциях типа

if ( a && something(a) )

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

Есть неплохая книжка Peter van der Linden "Expert C Programming: Deep C Secrets", довольно старая (1994 год), но актуальная как минимум в том, что касается вот таких неочевидных мест C.
[User Picture Icon]
From:ermiak
Date:Январь, 2, 2017 20:46 (UTC)
(Link)
Софтверная эмуляция "гонки сигналов"?
[User Picture Icon]
From:kincajou
Date:Январь, 2, 2017 20:55 (UTC)
(Link)
да тут уже написали - "неопределённое поведение", компилер волен сам выбирать порядок вычисления аргументов
[User Picture Icon]
From:ramlamyammambam
Date:Январь, 2, 2017 22:00 (UTC)
(Link)
Язык Си как острый топор: универсальный инструмент на все случаи жизни, но опасный в неопытных руках. :)
Рекомендую книжку Роберта Сикорда: https://www.ozon.ru/context/detail/id/31003198/
Куча подобных случаев разобраны здесь с объяснениями и примерами кода.
(Оставить комментарий)
Top of Page Разработано LiveJournal.com