LINUX.ORG.RU

приоритет операторов и gcc,clang

 ,


1

2

увидел на geekbrains тест:

    int p = 20, n = 12;
    n *= --p << 1 + p++ / 10;

чисто логически по таблице приоритетов я развернул так:

(p - 1) << (1 + (p - 1) / 10)

у меня clang, gcc разных версий выдает разный результат - 912, 960.

кто в курсе, у них какой ответ считается верным результатом?!

★★★★★

Оба ответа неверные. Здесь будет undefined behaviour из-за повторной модификации переменной в рамках одного выражения.

alexanius ★★
()
Ответ на: комментарий от alexanius

Оба ответа неверные.

Оба ответа верные, точнее. :)

Sorcerer ★★★★★
()

Правильный ответ: «Чтоб вас Ктулху обрыгал, никто в здравом уме не будет разгребать этот код»

JacobTwoTwo
()

нет верного результата. это Implementation Specific. Это выражение можно по разному разобрать и соотвественно результат будет разный.

anonymous
()
Ответ на: комментарий от anonymous2

undefined behaviour - такого ответа в тесте не было

Тогда тест подлежит сожжению

alexanius ★★
()

тесты тестами, но НЕ ИСПОЛЬЗУЙ конструкции, приоритет которых не очевиден или зависит от компилятора, в самом деле - просто насыпь туда скобок побольше и тогда будет четкий очевидный приоритет

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Приоритет конструкций не может зависеть от компилятора. Сыпать скобки, чтобы товарищам, которые не читают букварь, было проще читать код — такое себе занятие. Это ведь усложняет чтение нормальным людям. Может проще раздать буквари на один день?

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Код должен быть легко читаем. Тех, кто пишет плохо читаемый код, аноны считают геем, в плохом смысле слова.

anonymous
()
Ответ на: комментарий от Legioner

Это ведь усложняет чтение нормальным людям

спорить не буду, да и не видел чтоб по трезваку такой трэшняк писали :)

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от anonymous

Код должен быть легко читаем.

Лёгкая читаемость это субъективно. Туповатый трёхлетний ребёнок даже русский язык не всегда легко читает. Туповатый юрист даже паскаль легко не прочитает. Туповатый джуниор даже простейшие CTFE-вычисления может не осилить. Код должен быть легко читаем квалифицированным программистом. Квалифицированный программист знает приоритет операторов и необязательные скобки ухудшают читаемость кода.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Ни разу в жизни не видел квалифицированного программиста, который бы без букваря правильно бы расположил по приоритету +, >>, ^, | и &.

vzzo ★★★
()
Ответ на: комментарий от vzzo

Ни разу в жизни не видел квалифицированного программиста, который бы без букваря правильно бы расположил по приоритету +, >>, ^, | и &

плюсирую, причем умный человек, видя всю эту клоаку с пониманием приоритетов даже у квалифицированных казалось бы разработчиков компиляторов, не станет полагаться на зыбкие негарантированные сущности, а насыпет скобок, пусть это вызовет эстетическую боль у 0.3% тех, кто увидит его код

разве примеры топикстартера не показательны???

кстати, что там в стандартах типа MISRA, DO-* и подобных - не в курсе, но допускаю что там точно есть некий упор на недопустимость подобного кода

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

разве примеры топикстартера не показательны???

Имеено.

просто насыпь туда скобок побольше и тогда будет четкий очевидный приоритет

Вот «просто насыпьте скобок побольше», чтобы убрать UB. Слабо?

vodz ★★★★★
()
Ответ на: комментарий от vzzo

Ни разу в жизни не видел квалифицированного программиста, который бы без букваря правильно бы расположил по приоритету +, >>, ^, | и &.

Я просто держу этот букварь под рукой. ☺

Или используйте визуальный редактор или синтаксис Лисп.

beroal
()
Ответ на: комментарий от vodz

Вот «просто насыпьте скобок побольше», чтобы убрать UB. Слабо?

Запросто:

int p = 20, n = 12;
n = n * ((p - 1) << (1 + (p - 1) / 10));
p++;
Получается n == 912 как у шланга, так и у GCC, да и калькулятор такой же результат дает. И никаких UB, ибо нефиг плодить трэш. Чтобы понтануться перед одноклассниками? Или поразить работодателя как ловко кандидат ходить по лезвию ножа неопределенности? :)

>>> p = 20
>>> n = 12
>>> n = n * ((p - 1) << (1 + int((p - 1) / 10)))
>>> n
912

Даже пихтон скушает нормально обскобоченный код :)

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)
Ответ на: комментарий от I-Love-Microsoft

Запросто:

Так это и ТС сделал (и p++ то зачем?). Вы же обещали просто насыпать (), а не переписать.

vodz ★★★★★
()

Тут будет UB, а значит, любой ответ верный.

anonymous
()

Выкинуть такие тесты на помойку.

pftBest ★★★★
()

Какая разница? Поставь скобки. Если увидишь того, кто напишет такой код, смело бей в лицо.

anonymous
()

geekbrains

В мусор. Этот ресурс же сделан либо мыло.ру, либо яндехом.

Есть же нормальные платформы для обучения.

EXL ★★★★★
()
Ответ на: комментарий от andreyu

Самый обыкновенный UB, стандарт не регламентирует в каком порядке должны вичислятся аргруметы оператора сдвига (A << B). Компилятор сам решает что высщитать первым «А» или «B». Но так как при вычислении А и B используется значение p, и приэтом оба выражения модифицируют значение p (A: --p, B: p++) - то получаем UB.

zaz ★★★★
()
Ответ на: комментарий от andreyu

:) - пора спать.

Хотя при UB вернее будет «любой». Насколько я помню в стандарте гдето так и написано - если есть UB, то результат может быть любим (тоесть в данном случае любое число от -2G до 2G)

zaz ★★★★
()
Ответ на: комментарий от zaz

Это про implementation-defined behavior.

(тоесть в данном случае любое число от -2G до 2G)

ТС не уточняет каков размер int в задаче, а стандарт требует только выполнения short <= int <= long.

andreyu ★★★★★
()
Ответ на: комментарий от Legioner

«Если вы не можете объяснить это просто - значит, вы сами не понимаете этого до конца»(с)
В случае с кодом: он должен быть читаем для туповатого джуниора.

Aswed ★★★★★
()
Ответ на: комментарий от andreyu

В С++17 это не UB, т.к. порядок вычисления побочных эффектов именно у << и >> задан (чтобы работал треш вида cin >> i >> a).

vzzo ★★★
()
Ответ на: комментарий от vzzo

В С++17 это не UB, т.к. порядок вычисления побочных эффектов именно у << и >> задан (чтобы работал треш вида cin >> i >> a).

В топике речь о i++ + --i, не?

andreyu ★★★★★
()
Ответ на: комментарий от vzzo

В данном случае имеет значение то, что оператор <<, а не +.

1. Там операторы -- и ++ модифицирую одну и туже переменную p.
2. Оператор сдвига << не модифицирует переменную p.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

Оператор '<<' связывает первую модификацию со второй отношением sequenced-before, как это сделал бы ',', '||' или '&&' в старых версиях стандарта.

В моём предыдущем сообщении опечатка (точнее, лишний тег проставился), я имел в виду треш вида

cin >> i >> a[i]

vzzo ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.