|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Всем привет. Итак , упростил свой код по максимуму теперь он выглядит так и работает он как-то непонятно . Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
при пошаговом выполнении наблюдаю всё ход выполнения в main идет нормально до тех пор пока мы не доходим до второго цикла while , а затем - чудеса .По идее мы должны провалиться в getop, а мы мигом выскакиваем на return 0. Помогите разобраться почему так происходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:02 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81(*++argv)[0] Это что за бред? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:09 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov andron81(*++argv)[0] Это что за бред? это его величество Керниган )) возможно сейчас гуру пишет вот так **++argv так как argv это массив строк то (*++argv)[0] это перебор по каждому параметру , причем берем только первую букву ([0]). ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:14 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81, С какими параметрами ты запускаешь программу? Вот тут: Код: plaintext 1.
Смотри сначала ты префиксно переходишь к следующему аргументу. И получаешь "char *". Потом ты указатель разыменовываешь и получаешь "char". Потом ты с символом оперируешь как с указателем. Я вообще сомневаюсь что это должно компилироваться. Попробуй так: Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:20 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81 Dimitry Sibiryakov пропущено... Это что за бред? это его величество Керниган )) возможно сейчас гуру пишет вот так **++argv Позволь тебе предложить подход. Когда тебе что-то непонятно - ты берешь непонятный код и упрощаешь. До тех пор пока не станет понятно. Делаешь эквивалентные преобразования. Пред-и-пост инкременты - заменяешь на операцию и инкремент. Иначе выглядит так как будто ты - вьI36щик. А тыж не такой. Верно? В туловище цикла - вставь какую-то нейтральную операцию типа printf и поставь на нее брейкпоинт чтоб было понятно состояние цикла и что внутри. Ведь цикл делается именно ради тела цикла. Верно? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:23 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
petrav andron81, С какими параметрами ты запускаешь программу? Вот тут: Код: plaintext 1.
вот такие параметры 20 3 4 + * petrav Смотри сначала ты префиксно переходишь к следующему аргументу. И получаешь "char *". да потому что 0 параметр как я понимаю это имя моей программы. petrav Попробуй так: Код: plaintext 1.
попробую , но думаю не в этом суть. главное что условие выполняется. а NULL там будет или '\0' уже другой вопрос. Код: plaintext 1.
Но попробую ! ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:28 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81, Плохо ты книгу читал. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:31 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
mayton andron81 пропущено... это его величество Керниган )) возможно сейчас гуру пишет вот так **++argv Позволь тебе предложить подход. Когда тебе что-то непонятно - ты берешь непонятный код и упрощаешь. До тех пор пока не станет понятно. Делаешь эквивалентные преобразования. Пред-и-пост инкременты - заменяешь на операцию и инкремент. Иначе выглядит так как будто ты - вьI36щик. А тыж не такой. Верно? В туловище цикла - вставь какую-то нейтральную операцию типа printf и поставь на нее брейкпоинт чтоб было понятно состояние цикла и что внутри. Ведь цикл делается именно ради тела цикла. Верно? верно то верно. скорректировал код . Но есть тело или нет во внутреннем цикле загадка для меня каким образом цикл может щелкать сразу же к ретурну по кнопке F11 (VS) находясь на внутреннем вайле . то есть отладчиком дохожу до 2-го вайла , а затем нажимаю F11 и тут же оказываюсь на ретурне функции main. ведь даже если предположить , что условие не выполнилось внутреннего цикла (что тоже странно ведь для этого мы должны зайти в getop, а этого не происходит), то оказаться мы должны никак не в конце main. А если я вообще удалю внутренний цикл тогда всё логично работает . просто произойдет перебор аргументов. то есть к ретурну компилятор переходить не спешит :) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:42 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81 вот такие параметры 20 3 4 + * А это что типа калькулятор в польской записи? Код: plaintext 1.
В советском программируемом калькуляторе МК-52 была такая. Я на нём в школе мастерски программировал. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:43 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
petrav andron81 вот такие параметры 20 3 4 + * А это что типа калькулятор в польской записи? Код: plaintext 1.
В советском программируемом калькуляторе МК-52 была такая. Я на нём в школе мастерски программировал. да . это калькулятор выражений польской записи. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:44 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
petrav andron81, Плохо ты книгу читал. :) да ну ??? Если я допустил где-то ошибки, то и укажи мне на них. что я написал тут неправильно ? ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 22:58 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
petrav andron81, С какими параметрами ты запускаешь программу? Вот тут: Код: plaintext 1.
Смотри сначала ты префиксно переходишь к следующему аргументу. И получаешь "char *". Потом ты указатель разыменовываешь и получаешь "char". Потом ты с символом оперируешь как с указателем. Я вообще сомневаюсь что это должно компилироваться. Попробуй так: Код: plaintext 1.
Да, это я ерунды наговорил ближе к ночи. :) Сейчас разберусь, пардон ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 23:01 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Код конечно далёк от совершенства, но он работает. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
В первом while второе условие лишние. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 23:11 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Я не знаю. Этот код наверно надо вешать в качестве примера того как писать не надо. Безотносительно что там писал Кернинган. Его время прошло. И мутировать аргументы - это code-smell. По идее статик анализаторы здесь должны ругнуться. Грубо говоря если тебе зашел аргумент argc - то рассматривай его как константу. Крути какие угодно циклы но этот парамтер не трогай. Вот как-то так. Код: plaintext 1. 2. 3.
Существует также некая разумная метрика. Количество операторов на 1 строку кода. И когда ты пишешь такое Код: plaintext 1.
То в этом коде плохо ходить дебаггером. Т.к. в нем происходит слишком много всего. И проверки и мутации и разные сайд-эффекты. И программисту если надо трабл-шутить какой-то дефект или ошибку - придется все равно разваливать эту длинную строку на хотя-бы 4-5 атомарных строк смысл которых будет виден под отладчиком. И в командной разработке тех-лид должен не пропустить такой код. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 23:16 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
petrav В первом while второе условие лишние. Только, конечно, просто так удалять его не нужно. Там побочный эффект. Инкрементацию нужно в тело цикла перенести. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 23:26 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81, все нормально проваливается Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
... |
|||
:
Нравится:
Не нравится:
|
|||
17.05.2020, 23:36 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
andron81загадка для меня каким образом цикл может щелкать сразу же к ретурну по кнопке F11 (VS) находясь на внутреннем вайле Это называется оптимизация. Компилятор выкидывает код, который ничего не делает, потом код, результат которого нигде не используется. То, что останется, тасуется так как удобнее исполнять. В результате пошаговый отладчик становится бесполезным чуть более чем полностью. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2020, 00:53 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov andron81загадка для меня каким образом цикл может щелкать сразу же к ретурну по кнопке F11 (VS) находясь на внутреннем вайле Это называется оптимизация. Компилятор выкидывает код, который ничего не делает, потом код, результат которого нигде не используется. То, что останется, тасуется так как удобнее исполнять. В результате пошаговый отладчик становится бесполезным чуть более чем полностью. всё же это похоже на глюк. эту же исходную программу я сохранил вчера в текстовик и на другом компе сегодня его открыл и всё стало работать логично и закономерно проваливается в функцию getop(). у меня это бывало и раньше, и заметил , что всегда это проскакивает, когда код копипастишь из pdf версии книги. может какой-то мусор копируется дополнительно. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2020, 08:16 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
mayton Грубо говоря если тебе зашел аргумент argc - то рассматривай его как константу. Крути какие угодно циклы но этот парамтер не трогай. согласен , учту . mayton Существует также некая разумная метрика. Количество операторов на 1 строку кода. И когда ты пишешь такое Код: plaintext 1.
То в этом коде плохо ходить дебаггером. Т.к. в нем происходит слишком много всего. И проверки и мутации и разные сайд-эффекты. И программисту если надо трабл-шутить какой-то дефект или ошибку - придется все равно разваливать эту длинную строку на хотя-бы 4-5 атомарных строк смысл которых будет виден под отладчиком. И в командной разработке тех-лид должен не пропустить такой код. мне тем более как дилику выносит мозг, когда в условии цикла происходит всякие там *++argv. я бы тоже вынес это в тело. тоже думал , что для отладки это не пригодно. но так же думал, что надо привыкать к такому стилю. Принято, спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2020, 08:25 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
Игры с пред-пост инкрементом - это старый стиль. Его природа уходит корнями в ассемблер. Тоесть грубо говоря - не дружит с человеческим языком и математикой. Еще визуальной сложности может подбросить цикл for где в итерационном выражении программит играется с итерационным выражением. Переставляя плюсик то слева то справа. Это подкидывает больше WTF на код-ревью. Во многих языках которые возникли уже после С++ - от инкрементов отказались в пользу большей математичности и строгости формулы. Тоесть как-только у тебя возникает подозрение на UB - тут-же выбрасывай из выражения инкременты либо до выражения либо после в зависимости от того где стоит двойной плюсик. Есть даже забавные мозговыносящие вопросы на собеседовании как раз связанные с UB в выражении где есть и использование переменной несколько раз и ее-же инкременты. Вот у нас было https://www.sql.ru/forum/1130056/poryadok-vychisleniya https://www.sql.ru/forum/1309184-2/chto-neopredelyonnogo-v-c-c ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2020, 10:39 |
|
странный ход выполнения
|
|||
---|---|---|---|
#18+
кстати, непонятно причем здесь UB, и хотелось бы увидеть пример ... ... |
|||
:
Нравится:
Не нравится:
|
|||
18.05.2020, 13:11 |
|
|
start [/forum/topic.php?fid=57&msg=39958710&tid=2017429]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
36ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 285ms |
total: | 416ms |
0 / 0 |