• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Предложение Никогда так не делайте!

Юрий Ботов

Moderator
Команда форума
В одном из топиков нарвался на такой код "*readBuf++". НИКОГДА ТАК НЕ ДЕЛАЙТЕ!!!
Дело в том, что операции "взять указатель" и "инкремент" имеют в языке "С" одинаковый приоритет.
А выбор кто из них выполнится первым отдается компилятору, который решает с точки зрения краткости кода и/или скорости выполнения но ни как не с точки зрения ваших подразумеваний.
Тот кто писал код подразумевал *(readBuf++) но в результате оптимизаций с вероятностью 90% , будет сгенерирован код (*readBuf)++ а это сооовсем не то чего подразумевалось. Но хуже то что это не четко, а с вероятностью. То есть при отладке может быть один код, а в релизе совершенно другой!
При использовании указателей лишних скобок не бывает!
 
Последнее редактирование:
  • Like
Реакции: kab

pvvx

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

*ptr++ - Поиск в Google

How to increment a pointer address and pointer's value?

Оптимизация походу тут не при делах.

a++ - это post-increment. По логике инкремент производиться после взятия значения "a"
++a - перед взятием значения a

Так что путаницы никакой нет.

Даже в такой конструкции:

If (*ptr++ == 1 || *ptr++ == 2) … :)

PS: А что - опять ошибки в компиляторе для ESP (Xtensa LX106)? Это норма для малоиспользуемых CPU ядер :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
@ pvvx, stack overflow стал институтом стандартизации? :) не надо спорить. ТЫ в ветке для новичков, и им надо довести тот самый вывод: "При использовании указателей лишних скобок не бывает!". Будешь продолжать треп не по делу - безжалостно удалю.
Increment/decrement operators - cppreference.com
Тогда ошибка у вас в описании:
В одном из топиков нарвался на такой код "*readBuf++". НИКОГДА ТАК НЕ ДЕЛАЙТЕ!!!
Дело в том, что операции "взять указатель" и "инкремент" имеют в языке "С" одинаковый приоритет.
А выбор кто из них выполнится первым отдается компилятору
Разговора о скобках там нет. Не юлите :p
Если хотите найти неоднозначности, возьмите к примеру pritf(“\0123456789”) – там и будет зависимость от компилятора.
 
Последнее редактирование:

rst

Member
А выбор кто из них выполнится первым отдается компилятору, который решает с точки зрения краткости кода и/или скорости выполнения но ни как не с точки зрения ваших подразумеваний.
Неправда. Откройте описание синтаксиса языка си. Операции, имеющие одинаковый уровень приоритета, выполняются не как попало, а последовательно справа-налево или слева-направо. См. таблицу уровней приоритета и направление выполнения операторов на одном уровне:
Код:
Операции                                             |Ассоциативность
---------------------------------------------------------------------
() [] -> :: .                                        |Слева-направо
! ~ - ++ -- & *  (приведение типа) sizeof new delete |Справа-налево
.*  ->*                                              |Слева-направо
* / %                                                |Слева-направо
+ -                                                  |Слева-направо
<< >>                                                |Слева-направо
< <= > >=                                            |Слева-направо
==  !=                                               |Слева-направо
&                                                    |Слева-направо
^                                                    |Слева-направо
|                                                    |Слева-направо
&&                                                   |Слева-направо
||                                                   |Слева-направо
?:условное выражение                                 |Справа-налево
= *= /= := += -= &= ^= |= <<= >>=                    |Справа-налево
,                                                    |Слева-направо
Но в Вашем случае операция ++ - указана постинкрементная, т.е. - результатом данном операции (её возвращаемым значением) будет значение до операции, а не после.
 
Последнее редактирование:

kab

New member
Откройте описание синтаксиса языка си
Всё-таки на MCU не совсем си. Какой-то урезанный. И я не стал бы давать руку (ни правую, ни левую) на отсечение, что эта таблица приоритетов железно выполняется. И, даже при её корректном выполнении, держать в голове достаточно экзотичные сочетания операций ... Спасибо! В таких случаях существенно проще воспользоваться советом @Юрий Ботов и указывать приоритет явно, скобками. Как уже писалось ранее, при подаче умных советов (пусть даже правильных), надо учитывать, не заморочите ли Вы голову новичку. Я сам недавно в теме. И могу только посоветовать "советующим" - по стилю ответов берите пример с @Юрий Ботов и @tretyakov_sa. Извините за поучительный тон
 

rst

Member
Операторы с одинаковым приоритетом должны выполняться в порядке очередности, слева направо. Поэтому *readBuf++ эквивалентно (*readBuf)++.
Неправда. Почитайте описание синтаксиса си. Согласно таблице, что я привёл выше, операции * и ++ выполняются справа-налево.
А инкремент у автора - это постинкремент, поэтому для операции * будет взято значение readBuf до операции инкремента.
 

rst

Member
Всё-таки на MCU не совсем си. Какой-то урезанный. И я не стал бы давать руку (ни правую, ни левую) на отсечение, что эта таблица приоритетов железно выполняется.
А что-же это тогда - бейсик что-ли? ;)
Какая разница - MCU или неMCU? Си он везде си. Можете убедиться - берём IAR (for ARM), пишем:
Код:
char volatile *s3 = (char volatile *)&var;
printf("", *++--++++s3);
после компиляции (без оптимизации) получаем:
Код:
LDR.W    R0,??DataTable11_1
ADDS     R0,R0,#+1
ADDS     R0,R0,#+1
SUBS     R0,R0,#+1
ADDS     R0,R0,#+1
LDRB     R1,[R0, #+0]
Как можно заметить - полное соответствие приведённой мною таблице.

Как уже писалось ранее, при подаче умных советов (пусть даже правильных), надо учитывать, не заморочите ли Вы голову новичку.
Совет "изучить используемый язык" для новичка - это заморочит ему голову??? Если так, то ему лучше вообще не заниматься программированием.

Я сам недавно в теме. И могу только посоветовать "советующим" - по стилю ответов берите пример с @Юрий Ботов
Очевидно, что указанный товарищ не очень хорошо владеет предметом. Так что - как то странно молиться на него. Возьмите лучше учебник по си.
 

kab

New member
@rst
Хорошо, сдаюсь, не буду спорить с Вами насчет приоритетов в Си.
[off] В жизни мне приходилось писать прикладные программы на очень многих языках. Поэтому глубоко погрузится в какой-то один ЯП не получилось. Да и не очень хотелось. Но, надеюсь, какое-то общее понимание вопроса у меня сформировалось. И, при необходимости, копаться в документации я не отказываюсь. А в ответах @Юрий Ботов я чувствую жизненный практический опыт, аналогичный моему, но в своей сфере... По крайней мере, погрешности в чужом тексте увидел он. И в адвокатах он, по моему, не нуждается.
[/off]
 

=AK=

New member
Очевидно, что указанный товарищ не очень хорошо владеет предметом.
Конечно, можно напрячься и изучить все пыльные углы и закоулки языка С. Однако Ботов, как я понимаю, говорил не об этом. В сущности первый пост был о том, что лучше писать код, про который можно однозначно сказать, как он работает, даже без изучения назубок всей бессмысленной кривизны языка С. И в этом я с ним полностью солидарен. Именно по этой причине и я неверно определил очередность выполнения унарных операторов - потому что я пишу как раз такой "код со скобками", вместо того, чтобы зубрить все правила С наизусть.
 

pvvx

Активный участник сообщества
Всё-таки на MCU не совсем си. Какой-то урезанный. И я не стал бы давать руку (ни правую, ни левую) на отсечение, что эта таблица приоритетов железно выполняется.
Тогда это игрушка имеет свою таблицу и свой help (и возрастную группу). Иногда даже на реальный, встречаемый в природе аналог не походит, но всё равно такие игрушки любят. В таких случаях дети говорят - ну не доросла она до GCC или другого компилятора... :) Из таких "игрушек" в реальную жизнь очень мало можно чего перенести и заботиться что там всё не так не следует...
И, даже при её корректном выполнении, держать в голове достаточно экзотичные сочетания операций ... Спасибо! В таких случаях существенно проще воспользоваться советом @Юрий Ботов и указывать приоритет явно, скобками. Как уже писалось ранее, при подаче умных советов (пусть даже правильных), надо учитывать, не заморочите ли Вы голову новичку. Я сам недавно в теме. И могу только посоветовать "советующим" - по стилю ответов берите пример с @Юрий Ботов и @tretyakov_sa. Извините за поучительный тон
Если вам сложно понять, то ставьте скобки или описывайте последовательно. Для инвалидов тоже существуют выделенные места, чтобы им было проще и в этом ничего дурного нет.
Обычно такие сложные конструкции пишут чтобы код был более читаемым, а не в сотни строк.
Человек читает не по буквам, а абзацами. При длинной записи, с множеством лишних знаков конструкция не лезет "в абзац" и становится неразбираемой с первого взгляда...
Напомню - обычно первоклассники учатся читать по буквам, не используют умножения и деления, не воспринимают дроби... Если на большее не учить и не использовать, то так оно и прорастет.

Ваш (описанный выше) поучительный (ограничивающий других) лозунг (из разряда “слава партии”) является (более точно - требует) ограничением (установки запретов) свободы (желающим в этом разобраться). Примерно так хорошо читаемо? (я не литератор и извиняюсь, что не смог подобрать с десятками вложений, да и время на это жалко…).
В принципе читаемо, смысл примерно ясен, но вот автомат переведет в другой язык неверно. Т.е. никакой совместимости и переносимости, что человеком, что автоматом (правила у него указаны явно).

PS: Тема из разряда, что “чё” пишется в каких-то вариантах через “o” и пачка правил, но запомнить их сложно – тавайте писать “ЧЁ”.

Ну а к самой теме:
Если в коде компилятор встречает неоднозначность, то он вам он об этом сообщит warning-ом с описанием. Привычка собирать в Arduino примеры на ESP8266, с отключенными warning-ами до добра не доводит. Поставьте опции компилятору -Wall –Werror -Wpedantic и узнаете (прозреете) как вас там учат китайцы из Espressif писать программы с выключенными всеми warning … Потом, когда исправите тот кавардак, думаю на данную тему взгляните по другому.
 
Последнее редактирование:

kab

New member
Тогда это игрушка имеет свою таблицу и свой help (и возрастную группу). Иногда даже на реальный, встречаемый в природе аналог не походит, но всё равно такие игрушки любят. В таких случаях дети говорят - ну не доросла она до GCC или другого компилятора... :) Из таких "игрушек" в реальную жизнь очень мало можно чего перенести и заботиться что там всё не так не следует...

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

Ваш (описанный выше) поучительный (ограничивающий других) лозунг (из разряда “слава партии”) является (более точно - требует) ограничением (установки запретов) свободы (желающим в этом разобраться). Примерно так хорошо читаемо? (я не литератор и извиняюсь, что не смог подобрать с десятками вложений, да и время на это жалко…).
В принципе читаемо, смысл примерно ясен, но вот автомат переведет в другой язык неверно. Т.е. никакой совместимости и переносимости, что человеком, что автоматом (правила у него указаны явно).

PS: Тема из разряда, что “чё” пишется в каких-то вариантах через “o” и пачка правил, но запомнить их сложно – тавайте писать “ЧЁ”.

Ну а к самой теме:
Если в коде компилятор встречает неоднозначность, то он вам он об этом сообщит warning-ом с описанием. Привычка собирать в Arduino примеры на ESP8266, с отключенными warning-ами до добра не доводит. Поставьте опции компилятору -Wall –Werror -Wpedantic и узнаете (прозреете) как вас там учат китайцы из Espressif писать программы с выключенными всеми warning … Потом, когда исправите тот кавардак, думаю на данную тему взгляните по другому.
@pvvx
[off]
Вы меня несколько озадачили. Исходил из того, что здесь, в форуме, легкий трёп между чудаками, которые с свободное время, вместо того, чтобы пить пиво, занимаются всякими техническими игрушками. И испытывают от этого удовольствие. Даже позавидовал многим из вас, т. к. начиная с радиолюбительского пионерского возраста мечтал о больших проектах, но, ничего серьезного для себя так и не создал (не считая троих детишек, из которых двое неплохие программисты и все трое хорошие люди) - не сложилось. Попытался завязать общение с интересными людьми и на тебе, своими легкомысленными соображениями практически обидел некоторые стороны дискуссии...
Ребята (девчат я тут что-то не приметил), совершенно не хочу вступать ни в какую полемику не по одному вопросу с сложившимися людьми, которые уже знают чего хотят и имеют своё твердое представление по тому или другому вопросу. Каждый должен жить своими убеждениями. Но, по наличию некоторого опыта практического программирования, наивный, решил, что на этом форуме могу быть полезен совсем зеленой молодежи, помогая им делать самые начальные шаги. Но, выходит, что я какой-то деспот, и, следовательно, меня к молодежи и подпускать нельзя? Вроде бы никто из тех, кому я помогал переходить со студенческой скамьи во взрослую программистскую жизнь - не жаловались. Но тут призадумаешься :( ...
[/off]
 

Юрий Ботов

Moderator
Команда форума
"Всем спецам знающим С вопрос:
*a = *---*b/*-c;
Сколько тут ошибок?"

Пока только один откликнулся... остальным слабо? Головой без компилятора?

уточнюсь:
pvvx - "Ошибок там нет. Всё разбирается однозначно."
nikolz - сказал что "Компилятор сказал, что ошибок нет.Так как это выражение нигде далее не применяется, но сделал замечание что отсутствует ;" и как обычно удалил свой комментарий

жду правильного ответа от rst и других...
 
Последнее редактирование:

nikolz

Well-known member
Тогда это игрушка имеет свою таблицу и свой help (и возрастную группу). Иногда даже на реальный, встречаемый в природе аналог не походит, но всё равно такие игрушки любят. В таких случаях дети говорят - ну не доросла она до GCC или другого компилятора... :) Из таких "игрушек" в реальную жизнь очень мало можно чего перенести и заботиться что там всё не так не следует...

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

Ваш (описанный выше) поучительный (ограничивающий других) лозунг (из разряда “слава партии”) является (более точно - требует) ограничением (установки запретов) свободы (желающим в этом разобраться). Примерно так хорошо читаемо? (я не литератор и извиняюсь, что не смог подобрать с десятками вложений, да и время на это жалко…).
В принципе читаемо, смысл примерно ясен, но вот автомат переведет в другой язык неверно. Т.е. никакой совместимости и переносимости, что человеком, что автоматом (правила у него указаны явно).

PS: Тема из разряда, что “чё” пишется в каких-то вариантах через “o” и пачка правил, но запомнить их сложно – тавайте писать “ЧЁ”.

Ну а к самой теме:
Если в коде компилятор встречает неоднозначность, то он вам он об этом сообщит warning-ом с описанием. Привычка собирать в Arduino примеры на ESP8266, с отключенными warning-ами до добра не доводит. Поставьте опции компилятору -Wall –Werror -Wpedantic и узнаете (прозреете) как вас там учат китайцы из Espressif писать программы с выключенными всеми warning … Потом, когда исправите тот кавардак, думаю на данную тему взгляните по другому.
Браво, Вы опровергли основы структурного программирования а заодно и основы системного подхода.
 

rst

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

rst

Member
жду правильного ответа от rst и других...
Не дождётесь, потому что конкурсы в таком стиле мне не интересны.
Но если так уж хочется - то ошибок там неопределённое количество, так как не указаны типы данных и не указан язык.
Если язык си - как минимум не закрыт комментарий и не поставлено ';' в конце выражения. Остальные ошибки зависят от типов.
Хотя может в ардуйне так принято?... :confused:
 
Последнее редактирование:
Сверху Снизу