Comments 52
И уж если есть потребность в одинаковом куске кода, который не может быть завернут в функцию то вместо тупого копирования можно сделать из него макрос
Зачем макрос, когда можно написать inline функцию? По крайнйе мере в приведенном вами примере. inline функции пофвились в C 13 лет назад.
+1
Компиляторы под PIC реализуют стандарт ANSI X3.159-1989 «Язык программирования C», именно эту версию часто называют «ANSI C» или «C89», а 1989 год был чуть раньше чем 13 лет назад, так что inline там нет.
+4
Жаль. Просто для приведенного макроса
я не понимаю, модифицирует ли он глобальные переменные или локальные переменные функции, из которой он вызван. Он может делать и то и то. И это меня пугает.
#define getnextpathchar() ( utfModeFileName ? *++utf16path : *++temppath )
я не понимаю, модифицирует ли он глобальные переменные или локальные переменные функции, из которой он вызван. Он может делать и то и то. И это меня пугает.
+1
Ну культура именований переменных должна быть и так, чтобы понять где глобальная, а где локальная, но можно и параметры в макрос пихнуть и явно потом переменные указывать:
Кстати для пика актуальнее вообще вынести в обычную функцию (особенно если переменные глобальны и передается только условие) — значительно компактнее код получится, так как на работу с указателями используется довольно громоздкая обертка и штук пять костылей.
#define getnextpathchar(really, wherewhere, where) ( really ? *++wherewhere : *++where )
Кстати для пика актуальнее вообще вынести в обычную функцию (особенно если переменные глобальны и передается только условие) — значительно компактнее код получится, так как на работу с указателями используется довольно громоздкая обертка и штук пять костылей.
0
Я обоими руками за параметры, иначе не понятно, какие переменные этот макрос использует и какие меняет. Не видя определение макроса нельзя прочитать функцию.
Макросы я не люблю вот по этому: habrahabr.ru/post/150970/#comment_5123005
Но раз C89, то вариантов действительно нет.
Макросы я не люблю вот по этому: habrahabr.ru/post/150970/#comment_5123005
Но раз C89, то вариантов действительно нет.
0
ох как я не люблю готовые библиотеки, особенно скачанные с разных фан-сайтов непрограммистами для непонятно чего.
0
UFO just landed and posted this here
Именно так.
+1
А все-таки индусский, ведь скорее исповедование шиваизма, а не действительное гражданство Индии прямой путь к таковому.
0
UFO just landed and posted this here
Искренне восхищен познаниями в столь тонких материях, сам я в них к сожалению как свинья в апельсинах, поэтому индусский для меня это как для римлян варварский — суть — непонятный в первую очередь; ксенос может быть но -фобос никак, я боюсь не кода как такового, или огнепоклонника в чалме с тем что у него в голове такой код, а того что такой код был в моих программах.
И ни в коем случае не хочу обидеть представителей столь древней цивилизации провернувшей сексуальную революцию задолго до того как мои предки начали шариться где-то в лесах и промышлять собирательством, язычеством и прочим воруй-убивай (гусей н ебыло). А слово «шиваизм» просто пришлось кстати, для меня любой набор звуков в противоестественной уху позе, например, «абухрантропия» или «нонемичизм» будет невольно ассоциироваться с тем, что я видел в исходниках микрочипа.
И ни в коем случае не хочу обидеть представителей столь древней цивилизации провернувшей сексуальную революцию задолго до того как мои предки начали шариться где-то в лесах и промышлять собирательством, язычеством и прочим воруй-убивай (гусей н ебыло). А слово «шиваизм» просто пришлось кстати, для меня любой набор звуков в противоестественной уху позе, например, «абухрантропия» или «нонемичизм» будет невольно ассоциироваться с тем, что я видел в исходниках микрочипа.
+1
А вот не соглашусь. Я правда не так много читал древне индийских текстов. Конечно, в них очень выраженна тяга к классификации и обобщениям, но у них же есть просто какая-то неутомимая тяга к перечислениям всего и вся. Я вот как-то после чтения Камасутры вернулся к какому-то куску идийского кода, и я прям ощутил родство текстов. То есть, вот эта любовь к длинным кускам кода, вполне возможно, часть культуры. Они не видят в этом ничего плохого.
+1
UFO just landed and posted this here
Указание авторства, лицензия, наличие ссылки либо сам оригинал. Однако! GNU&open source же =)
+1
Нет, я имею в виду именно перечисления. То есть, насколько я понимаю, брахману было мало сказать в тексте: существуют такие-то и такие классы явлений, вот их признаки. Там ещё в конце каждого такого определения идёт длинный список (насколько я понимаю, по мнению автора, исчерпывающий) все возможные варианты этого явления. Вот. Мне и кажется, что, конечно, они мастера обобщать и классифицировать, но и перечислить все детали им тоже приятно. Насколько я могу судить, индийские математики тоже хороши именно в тех задачах, где требуется разбирать множество вариантов. Поэтому, вот совсем не факт, что ручное развёртывание циклов — это говнокод.
0
Это странно, у меня другая информация по этому поводу:
1. Чукча преклонных годов, исповедующий шиваизм, никак не может быть индусом. Это новое веяние в индийской маркетологии — дать возможность быть индусом не индийцам, в оригинале же такого не было.
2. Индиец по умолчанию рождается индусом, а потом может выбирать какую-то религию.
Возможно, подправят более знающие люди )
1. Чукча преклонных годов, исповедующий шиваизм, никак не может быть индусом. Это новое веяние в индийской маркетологии — дать возможность быть индусом не индийцам, в оригинале же такого не было.
2. Индиец по умолчанию рождается индусом, а потом может выбирать какую-то религию.
Возможно, подправят более знающие люди )
0
Автор справедливо указал что индусов среди программистов полно и в нашей стране
+1
А разве первый пример не будет ругаться, что SPIBUF при последнем использовании не определен? Да и при рефакторинге куда-то делось уменьшение localCounter.
0
Ругаться не должно. Это регистр куда положатся данные пришедшие по SPI.
0
SPIBUF не определен в обоих кусках (на то они и куски — он определен выше и это не суть), а если читать внимательно то уменьшение указателя компенсируется его последующим увеличением. В этом то и фокус — писать код так чтобы никто не разобрался, но выглядело умно'.
0
> то уменьшение указателя компенсируется его последующим увеличением
Вам пишут про то, что у вас бесконечный while ();
localCounter-- остро не хватает.
Вам пишут про то, что у вас бесконечный while ();
localCounter-- остро не хватает.
+2
При не очень умном компиляторе код
вполне может оказаться заметно хуже, чем
А окружающие будут думать, что второй вариант — это «индийский» код. Обидно, да? Я тут каждый такт вылизываю, а они пальцем тычут :D
while(cntr--) *ptr++=a;
вполне может оказаться заметно хуже, чем
if(cntr){
--ptr;
do {
*++ptr=a;
}while(--cntr);
++ptr;
}
А окружающие будут думать, что второй вариант — это «индийский» код. Обидно, да? Я тут каждый такт вылизываю, а они пальцем тычут :D
+4
UFO just landed and posted this here
Вероятно при любом компиляторе, memset должен быть вылизан до вас, и тогда зачем изобретать велосипед:
Ну а если вопрос действительно в тактах, то это уже про ассемблер, так как компилятор может и поменяться.
memset(ptr, a, cntr);
Ну а если вопрос действительно в тактах, то это уже про ассемблер, так как компилятор может и поменяться.
+1
memset работает, только если sizeof(*ptr)==1, не так ли? А в ассемблере разворачивание цикла вполне может занять несколько дней и превратить 5 строчек в 50 (причем почти без копипаста) — и при этом ускорить его в 10 раз. С полной потерей читаемости и возможности поддержки. И что тогда люди скажут?
+1
И все-таки интересно в каком компиляторе второй пример компилируется в более оптимальный код, или это гипотетический пример?
0
Пример гипотетический. Надеюсь, что в наше время таких компиляторов не осталось. Но можно попроверять.
0
Обидно, да? Я тут каждый такт вылизываю, а они пальцем тычут :D
Ради лулзов набросал тут на бумажке очистку памяти в цикле и без:
Итого (3+2)*256+2 циклов.
Итого 256 циклов.
Линейная программа выполнится в 5 раз быстрее! :)Сишный компилятор такое оптимизирует?
Ради лулзов набросал тут на бумажке очистку памяти в цикле и без:
start
clrf INDF ;1 cycle
incf FSR, f ;1 cycle
decfsz counter ;1(2 if Zero) cycles
goto start ;2 cycles
;end :)
Итого (3+2)*256+2 циклов.
clrf 0x00 ;1 cycle
clrf 0x01 ;1 cycle
...
clrf 0xff ;1 cycle
Итого 256 циклов.
Линейная программа выполнится в 5 раз быстрее! :)Сишный компилятор такое оптимизирует?
0
хм… код отпарсило криво
start
clrf INDF ;1 cycle
incf FSR, f ;1 cycle
decfsz counter ;1(2 if Zero) cycles
goto start ;2 cycles
;end :)
Итого (3+2)*256+2 циклов.
clrf 0x00 ;1 cycle
clrf 0x01 ;1 cycle
…
clrf 0xff ;1 cycle
Итого 256 циклов.
start
clrf INDF ;1 cycle
incf FSR, f ;1 cycle
decfsz counter ;1(2 if Zero) cycles
goto start ;2 cycles
;end :)
Итого (3+2)*256+2 циклов.
clrf 0x00 ;1 cycle
clrf 0x01 ;1 cycle
…
clrf 0xff ;1 cycle
Итого 256 циклов.
0
Единственное где использую линейный код — это задержки порядка микросекунд и прочие супер тайм-критикал вещи. В тех же местах в топике, которые я привел, быстродействие — самая последняя вещь о которой надо думать, например форматирование SD карты (а именно оно в примере) происходит совсем не часто.
PS. А можно я ваш код чуток пооптимизирую, точнее поизвращаюсь ;)
Исхожу из того что 256баранов байт лежат в одной банке, что ну уж очень логично, особенно в 16-м семействе пиков (судя по командам), тогда:
У меня на 256 циклов меньше.
PS. А можно я ваш код чуток пооптимизирую, точнее поизвращаюсь ;)
Исхожу из того что 256
clrf FSR ; этого не то чтобы нет в исходном примере, его просто плохо видно :)
start:
clrf INDF ;1 cycle
incfsz FSR, f ;1(2 if Zero) cycles
goto start ;2 cycles
;end
У меня на 256 циклов меньше.
+1
В своё время приходилось править баги в реализации CMSIS от NXP для мкроконтроллеров NXP. Некоторые баги были связаны с тем, что кто-то неправильно прочитал даташит, нектороые — просто логические баги. А если хотите совсем кошмар, загляните во внутренности uIP. Хотя там всё as is и вам никто ничего не должен.
0
> Больше кода — больше профит!
раньше это была повсеместная практика, платили за строчки кода…
раньше это была повсеместная практика, платили за строчки кода…
0
>не стесняйтесь делать и так, memset для лузеров, а это живые деньги
Я раньше тоже писал T1COM = 0b01100100;
А теперь пишу T1CONbits.RCIF = 0b110; //110 — HSI 8MHz
Потому что если заполнить этот gDataBufer мемсетом, то потом через неделю уже не вспомнишь, что там и почему.
>int FSerror (void)
>{
> return FSerrno;
>}
Это очевидная заглушка для реализации собственного обработчика пользователем
Пустая шапка очевидно генерируется автоматически их системой разработки и необходима для правильной работы систем контроля версий, автоматических сборочных конвейеров и т.д.
>Линейная программа работает значительно быстрее, не тратя времени на операторы условий и переходы, и содержит больше строк кода
Стебаться над этим можно только приведя для сравнения то, что нагенерит компилятор в итоге.
Я раньше тоже писал T1COM = 0b01100100;
А теперь пишу T1CONbits.RCIF = 0b110; //110 — HSI 8MHz
Потому что если заполнить этот gDataBufer мемсетом, то потом через неделю уже не вспомнишь, что там и почему.
>int FSerror (void)
>{
> return FSerrno;
>}
Это очевидная заглушка для реализации собственного обработчика пользователем
Пустая шапка очевидно генерируется автоматически их системой разработки и необходима для правильной работы систем контроля версий, автоматических сборочных конвейеров и т.д.
>Линейная программа работает значительно быстрее, не тратя времени на операторы условий и переходы, и содержит больше строк кода
Стебаться над этим можно только приведя для сравнения то, что нагенерит компилятор в итоге.
+5
Искренне надеюсь, что хоть комментарии там сгенерированы автоматически. Поистине, моя вера в человечество бесконечна.
0
Вообще не терплю копипаст в программировании. Если возникло желание что-то скопировать то сразу задумываюсь где и что надо переписыватьглавное при этом не переписать до анти-паттерна over-optimization.
0
while (localCounter--)
{
SPIBUF = 0xFF;
while (!SPISTAT_RBF);
*localPointer++ = SPIBUF;
}
Если localCounter == 0, что мы получим после проверки этого условия? Соответствует ли это задумке и изначальному коду?
{
SPIBUF = 0xFF;
while (!SPISTAT_RBF);
*localPointer++ = SPIBUF;
}
Если localCounter == 0, что мы получим после проверки этого условия? Соответствует ли это задумке и изначальному коду?
0
Минусминус после переменной, значит проверяется ее значение до декремента, так что проверка на ноль и выход из цикла не начиная его. Эквивалент:
loop:
if (0 != localCounter) {
localCounter = localCounter - 1;
...
goto loop;
}
-1
какое будет значение переменной localCounter после этого?
0
Разница будет в значении localCounter после цикла, в одном случае оно останется 0, а в другом станет -1 в том или ином виде.
0
Угу, а теперь понимаем, что каунтеры обычно у нас unsigned и думаем что случится при следующей проверке этого условия.
+2
" -1 в том или ином виде", -1 в виде unsigned это 0xF...F по соответствующей ширине, но видимо надо было привести кусок чуть шире:
Но даже если есть задача написать полный эквивалент, а не функциональный в данном контексте, то достаточно внести декремент внутрь операторных скобок, что увеличит исходный код всего на одну строку.
Данный вариант внес в топик чтобы не было недопониманий, хотя кто-нибудь другой вполне возможно назвал это пустой придиркой. Все-таки тема не про тесты на языке си, хотя такую тоже интересно было бы поднять, интересно кто как берет программистов на работу. Вот у меня, например, накопилось с десяток заданий-тестов.
#if defined __C30__ || defined __C32__
{
BYTE* localPointer = ioInfo.pBuffer;
WORD localCounter = ioInfo.wNumBytes;
// здесь тот самый, приведенный кусок
// переменные локальнее некуда
}
#endif
Но даже если есть задача написать полный эквивалент, а не функциональный в данном контексте, то достаточно внести декремент внутрь операторных скобок, что увеличит исходный код всего на одну строку.
Данный вариант внес в топик чтобы не было недопониманий, хотя кто-нибудь другой вполне возможно назвал это пустой придиркой. Все-таки тема не про тесты на языке си, хотя такую тоже интересно было бы поднять, интересно кто как берет программистов на работу. Вот у меня, например, накопилось с десяток заданий-тестов.
0
Они, наверное, пишут код правильно и аккуратно, но перед сдачей проекта в спешном порядке инлайнят все, что можно :)
0
Ну они же написали!
Так что все оптимизмрубт потом:)
Remarks:
Optimize code later
Так что все оптимизмрубт потом:)
+2
А что я должен был получить в 2012 году, набрав 95 в гугле?
0
Прошло 10 лет с момента публикации, однако, судя по всему, ошибки так никто и не заметил.
// а это полный аналог,
А вот и не полный. В оригинальном коде по завершению блока localPointer будет указывать на последний принятый байт, а в вашей - на следующий за ним. Возможно, конкретно в данном применении разницы и не будет, но назвать такое полным аналогом - нельзя.
А если это становится важно, то обойтись 4-мя строчками уже не выйдет, т.к. нужна еще одна проверка. В итоге, разница с исходным становится уже и не такая большая.
0
Sign up to leave a comment.
Индусский код в Микрочипе