1 / 1 / 0
Регистрация: 20.09.2017
Сообщений: 132
|
|
1 | |
C++ магия вывода17.07.2023, 22:56. Показов 904. Ответов 11
Метки нет Все метки)
(
В процессе решения тестов попался такой код.
Вопрос: почему он выводит "12 11", хотя по логике должен вывести "11 11" Последовательность в моем понимании: выводим х после увеличения. Это 11. затем возвращаем объект ostream для обработки вывода пробела (" "). после чего возвращаем его же для вывода y++, которое, по сути, должно вернуть предыдущее значение, т.к. у нас постфиксный инкремент. А это значение - 11. Тогда откуда вообще берется 12 11? Или компилятор зачем-то "оптимизирует" и переставляет местами операции, в силу чего y++ выполняется раньше, нежели вывод х? UPD: на 17-20 стандартах выводит 11 11. Тогда почему в 14 происходит то, что происходит
0
|
17.07.2023, 22:56 | |
Ответы с готовыми решениями:
11
Магия отладчика
Строки char и магия |
Модератор
![]() ![]() |
|
17.07.2023, 23:09 | 2 |
Хм, перепробовал разные компиляторы, последний msvc 17.6.5, последний clang 16 (простой и cl), mingw 11 (под виндой и в wsl, грубо говоря на линуксе). Все в релизах, но clang + wsl еще и в дебаге, в итоге везде на выводе 11 11, только у меня в проекте с++20
0
|
![]() 3765 / 2693 / 762
Регистрация: 29.06.2020
Сообщений: 9,917
|
|
17.07.2023, 23:16 | 3 |
![]() Решение
Патамушта x и y указывают на один и тот же объект.
А в С++ https://en.cppreference.com/w/... eval_order ![]() Если по конкретному примеру, то он ведет себя без UB начиная от С++17.
1
|
Вездепух
![]() ![]() ![]() 12847 / 6714 / 1805
Регистрация: 18.10.2014
Сообщений: 17,009
|
|
18.07.2023, 05:12 | 4 |
![]() Решение
По какой именно логике он должен был вывести
11 11 ?Именно в С++17 и после гарантируется 11 11 .Потому что до C++17 в выражении std::cout << x << " " << y++ (эквивалентно std::cout << x << " " << x++ ) не было точек следования, которые разделяли бы модификацию переменной x и независимое чтение переменной x . А значит - поведение не определено.Только в стандарте С++17 в описании операторов << и >> появился пункт
1
|
![]() 4038 / 2583 / 431
Регистрация: 09.09.2017
Сообщений: 11,534
|
|
18.07.2023, 09:11 | 5 |
Не то чтобы совсем не определено.
Оператор x++ заставляет сначала считать предыдущее значение, и лишь потом модифицировать. То есть вывод второй 11 гарантировано произойдет раньше увеличения. А вот попадет ли в первый Х старое или новое значение, неизвестно. У вас, berkut234, похоже, новое.
0
|
Вездепух
![]() ![]() ![]() 12847 / 6714 / 1805
Регистрация: 18.10.2014
Сообщений: 17,009
|
|
18.07.2023, 09:33 | 6 |
Это в данном случае совершенно не важно. К неопределенному поведению (до С++17) приводит конфликт между первым и вторым обращением к
x . А что там "сначала и потом" происходит внутри отдельного x++ - это дело десятое.Нет. Чтение при первом (слева) доступе к x и модификация во втором (слева) доступе к x не упорядочены относительно друг друга. Поведение не определено. Не "старое или новое значение", а потенциальное пресловутое форматирование жесткого диска, ибо поведение не определено вообще.
0
|
![]() 4038 / 2583 / 431
Регистрация: 09.09.2017
Сообщений: 11,534
|
|
18.07.2023, 10:02 | 7 |
Как раз это единственное, что важно. ТС ведь спрашивал именно об этом.
И повторили сказанное мной... Если производители вашего компилятора и операционки настолько наркоманы, чтобы такое делать - меняйте их на более адекватных.
0
|
Вездепух
![]() ![]() ![]() 12847 / 6714 / 1805
Регистрация: 18.10.2014
Сообщений: 17,009
|
|
18.07.2023, 10:03 | 8 |
Нет. ТС сам не знал, о чем спрашивал. Вся полученная ТС информация - для ТС в новинку.
0
|
![]() 4038 / 2583 / 431
Регистрация: 09.09.2017
Сообщений: 11,534
|
|
18.07.2023, 10:40 | 9 |
ТС просил объяснить наблюдаемое поведение. Соответственно, надо не только процитировать ему стандарт, но и объяснить механизм такого поведения. Не забывайте, многие вещи из стандарта можно спокойно нарушать, если знаешь что делаешь. UB это не обязательно ужас-кошмар, а иногда вполне удобные хаки.
0
|
![]() 759 / 456 / 213
Регистрация: 19.12.2016
Сообщений: 1,815
|
||||||
18.07.2023, 12:00 | 10 | |||||
Вот еще одна страшная вещь, которую я встретил.
0
|
Вездепух
![]() ![]() ![]() 12847 / 6714 / 1805
Регистрация: 18.10.2014
Сообщений: 17,009
|
|
18.07.2023, 20:37 | 12 |
Программа, которая не завершает свой вывод переводом строки в конце - это действительно ужас, летящий на крыльях ночи. (Срочно промыть глаза, срочно промыть глаза...)
0
|
18.07.2023, 20:37 | |
Помогаю со студенческими работами здесь
12
Магия со статическими массивами Магия виртуального деструктора
Шаблонная магия и метод класса Магия препроцессора, или вложенные макросы! Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
![]() |
Новые блоги и статьи
![]() |
||||
Неблокируемый стек в C++26: реализуем простой сборщик мусора
stackOverflow 02.03.2025
Многопоточные приложения требуют надежных и производительных структур данных, способных эффективно работать в условиях конкурентного доступа. Неблокируемые структуры данных представляют собой особый. . .
|
Шаблон REQ/REP в ZeroMQ: сверхбыстрый обмен сообщениями в C++ и Python
stackOverflow 02.03.2025
Построение высоконагруженных распределенных систем требует надежного и производительного механизма обмена сообщениями. ZeroMQ выделяется среди прочих решений своей невероятной скоростью работы и. . .
|
Нестандартные приемы работы с итераторами в C++
stackOverflow 02.03.2025
Итераторы - один из краеугольных камней C++, предоставляющий универсальный механизм обхода и манипуляции данными в контейнерах. Появившись как замена небезопасным указателям, они эволюционировали от. . .
|
Лексический анализ и регулярные выражения в C++26
stackOverflow 02.03.2025
Лексический анализ - ядро любого компилятора и инструмента обработки текста. Каждый программист сталкивается с задачами парсинга строк, обработки файлов конфигурации или анализа пользовательского. . .
|
Подробно о std::mdspan в C++23
stackOverflow 02.03.2025
Работа с многомерными массивами данных традиционно была одной из сложных задач в C++. Программистам приходилось создавать собственные абстракции или использовать сторонние библиотеки для эффективной. . .
|
Колмогоровская сложность в C++: Путь к совершенному коду
stackOverflow 02.03.2025
Абстрактная математическая теория Колмогорова стала мощным средством оценки и улучшения программного кода. Сложность алгоритма - не только в его вычислительной эффективности, но и в том, насколько. . .
|
Изменения в C# 14
stackOverflow 02.03.2025
Одно из самых значимых изменений в C# 14 - поддержка коллекционных выражений, которые позволяют создавать и инициализировать коллекции с помощью нового лаконичного синтаксиса. Это нововведение. . .
|
Разработка кроссплатформенного мобильного приложения для iOS/Android на C++
bytestream 02.03.2025
C++ как язык программирования высокого уровня с прямым доступом к аппаратным ресурсам позволяет создавать приложения, работающие одинаково быстро как на iOS, так и на Android устройствах. Ни для кого. . .
|
Аутентификация/авторизация на Golang
bytestream 02.03.2025
Go предлагает множество возможностей для создания надежных систем аутентификации. Встроенные криптографические пакеты, высокая производительность и простота параллельной обработки запросов делают его. . .
|
Нововведения TypeScript 5.8
bytestream 02.03.2025
TypeScript 5. 8 приносит много возможностей и оптимизаций, которые существенно расширяют границы типобезопасного программирования на JavaScript. Эта версия включает ряд значительных улучшений в работе. . .
|