LINUX.ORG.RU
Ответ на: комментарий от lenin386

Приоритеты операций — это про то, как выражение парсится. А не про то, в каком порядке подвыражения вычисляются (естественно, кроме элементарного правила что операнды должны вычислиться до вычисления оператора. Но при этом вычисления в операндах могут перемежаться в любом порядке).

utf8nowhere ★★★
()

You scored 5 points, congratulations! You know exactly what you don’t know.

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

strictly conforming program - uses only well-defined language constructs, that is constructs with a single behavior

так что да, строго удовлетворять требованиям стандарта, а не компилятора.

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

Там ещё нельзя вызывать никакие функции кроме определённых в стандарте (ну и в самой программе, естественно).

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

Из блоба - нельзя. Блобу вообще доверия нету, мало-ли что там понаписали внутри. А если ты опенсорсную фигню тащишь, то будь добр её проверять и отвечать за неё как и за остальную свою программу, фикся баги в ней в случае если автор оригинала не хочет и говорит что это фича такая. Понятно что на практике обычно кладут болт, но что-то мне подсказывает что если из-за бага в новой версии curl у тебя АЭС бабахнет, то на бутылку ты поедешь, а не автор curl.

peregrine ★★★★★
()

Когда мне на собеседовании задают такие задачи, я просто говорю, что я такое говно не пишу и никому писать не советую, так как это UB на UB UB погоняет.

deep-purple ★★★★★
()
Ответ на: комментарий от praseodim

Программа получится сильно завязанной на gcc

А во всей индустрии только два-три компилятора этот дебилизм и поддерживают — тот же MSVC из коробки идет с перманентно активным no-strict-aliasing.

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

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

И у меня, и у других, и вообще на всех минимально популярных компиляторах, в том числе каком-нибудь экзотическом «tiny c». «Не работать» будет только у того, кто мне машет стандартом и говорит «это не может работать».

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

Ну а теперь скажи не подглядывая, какой результат выдаст gcc для

Я п выдал ноль. Сейчас допишу мою реакцию после прочтения правильного ответа.

UPD: ха-ха, прикольно. Я даже не знал, как битовый сдвиг на x86 себя ведет при выходе за границы числа бит. По сути там x >> (v % 32) .

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

Когда мне на собеседовании задают такие задачи, я прощаюсь и ухожу.

fulmar_lor
()
Ответ на: комментарий от byko3y

На самом деле ситуация обычно другая. Те, кто выкидывают стандарт Си и машут руками, что «всё будет работать», в какой-то момент таки сталкиваются с тем, что код перестаёт работать.

Например, вот статья на хабре (https://habr.com/ru/post/592233/). Там много текста про проблемы, но в конце есть пример переписки в багзилле по поводу знакового переполнения. После изменения в gcc один участок кода перестал работать так, как ожидал его автор - он знал про UB, но полагался на конкретное поведение компилятора. В переписке автор UB кода демонстрировал типичную логику: требовал отменить стандарт и вернуть старое поведение gcc, заявлял, что «ему как автору виднее», что он «разбирается в вопросе лучше» и «какая часть его аргументации разрабам не ясна» и т.п.

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

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

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

Я даже не знал, как битовый сдвиг на x86 себя ведет при выходе за границы числа бит.

А теперь используй флаг -O2 при компиляции

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

Ну типа да, но от меня всё допытывались, а что всё-таки произойдёт. Кривя рожу, сказал, что на «типичной» реализации произойдёт.

utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)

Ответил на все вопросы, что не знаю, получил 5 баллов за знание сишки. Сишку я не знаю) Учил в универе, но это не в счет.

goingUp ★★★★★
()

Опрос не про си, а про то что «НЕТУ ТЯГО ЧЯО Я нИ НАЮ» поэтому чисто психологически многие вот ответ «I don’t know.» просто не принимают во внимание. Да и сам этот ответ некорректный так как есть просто несколько ответов в зависимости от условий. Так что этот вопрос донный и не про си вовсе, а про психологический трюк.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от mxfm

Например, вот статья на хабре

Статья с неправильным названием.

После изменения в gcc один участок кода перестал работать так, как ожидал его автор - он знал про UB, но полагался на конкретное поведение компилятора

Ага, это прекрасно:

— я раньше делал так для проверки переполнения, теперь этот код не работает

— да, в стандарте это — УБ, используйте проверку переполнения, согласованную со стандартом

— нет, вы не поняли, это теперь не работает, раньше работало, теперь нет

— это лишь проверка переполнения, перестаньте эксплуатировать УБ и проблем не будет

— вы тупой? говорю вам, не работает теперь, код поломали?

— …

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

— нет, вы не поняли, это теперь не работает, раньше работало

— нет, вы не поняли, это и раньше не работало

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

Товарищ, а почему ты i++ + ++i с такой лёгкостью заменил на ++i + ++i ? В примере из lurkmore одинаковые операции, и поэтому там действительно UB, потому что не понятно, какой ++ первым читать. Но в примере 5 subj разные операции, у них разный приоритет, и там абсолютно понятно, что считать первым.

lenin386 ★★★★
()
Последнее исправление: lenin386 (всего исправлений: 1)
Ответ на: комментарий от utf8nowhere

Приоритеты операций — это про то, как выражение парсится.

Чё? А это выражение что не парсится штоле?

А не про то, в каком порядке подвыражения вычисляются

Э-э-э, товарищ. как парсится, так и вычисляется. Это очевидно.

Но при этом вычисления в операндах могут перемежаться в любом порядке

Только при условии равных приоритетов, а тут они не равные.

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

Но в примере 5 subj разные операции, у них разный приоритет, и там абсолютно понятно, что считать первым.

Про «приоритет» префиксного инкремента по отношению к постфиксному имеет смысл говорить только когда они стоят так: ++i++. «Приоритет» говорит о том, как это распарсится¹. Как эквивалент (++i)++ или ++(i++). Всё.

Когда инкременты в разных операндах, типа как в i++ + ++i, вообще нет смысла говорить про приоритет одного инкремента по отношению к другому.


  1. Вообще, стандарт не говорит о «приоритетах», табличка с приоритетами следует из грамматики. Я думаю это и так известно. Но на всякий случай.
utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 2)
Ответ на: комментарий от lenin386

Приоритеты операций — это про то, как выражение парсится.

Чё? А это выражение что не парсится штоле?

Парсится. И?

А не про то, в каком порядке подвыражения вычисляются

Э-э-э, товарищ. как парсится, так и вычисляется. Это очевидно

… не так.

Но при этом вычисления в операндах могут перемежаться в любом порядке

Только при условии равных приоритетов, а тут они не равные.

При чём тут вообще приоритеты. 🤦‍♂️

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

Э-э-э, товарищ. как парсится, так и вычисляется. Это очевидно.

Тебе на протяжении всего треда пытаются донести мысль, что НЕТ. Это НЕ ТАК. Компилятор может выполнять вычисления в ином порядке в строке, нежели читает программист.

Именно поэтому и UB тут.

как парсится, так и вычисляется

Ещё раз. Попробуй внимательно прочитать и осмыслить следующее утверждение: НЕТ.

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

Например, вот статья на хабре (https://habr.com/ru/post/592233/). Там много текста про проблемы, но в конце есть пример переписки в багзилле по поводу знакового переполнения

Я читал эту статью и даже отметился в комментах. Здесь не правы авторы GCC, в абсолютно всех остальных компиляторах и старых версиях GCC этот код работает. Это называется «фактический стандарт», который более важен, чем комитетская макулатура, потому что он ФАКТИЧЕСКИЙ, то есть, все компилятор уже его придерживаются, поскольку не могут ждать еще десять лет пока комитетские вахтеры дочухают жопу и примут наконец это поведение в стандарт.

byko3y ★★★★
()

Не знаю как в линукс, но в микроконтроллерах использую только stdint.h, уже даже не помню какой там размер у разных int

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

Жесть. «Веселее» всего тут не то, что такой felix-gcc существует (мало ли упоротых), а то, что ещё и автор статьи на хабре при цитировании не смеётся над ним, а очень даже наоборот:

На резонную просьбу felix-gcc исправить неожиданный баг компилятора ответил пользователь под ником Andrew Pinski. Будучи разработчиком gcc, Andrew Pinski заметил, что данное поведение не является ошибочным. Более того, он сам оказался автором изменения в коде компилятора, которое и создало столь странный результат.

CrX ★★★★★
()

You scored 5 points, congratulations!

В общем-то не удивлен, давно уже пишу на C и только на C

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

Так и есть, ещё хуже, что люди типа автора и @byko3y, обученные научным тыком, не находят в подобном проблем.

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

Почти так же, только в начале удивился ещё. 5/5

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

Нет, дело не в стандарте. Если отбросить теоретизирования и необычные настройки компиляторов, то первый, второй и четвёртый вопросы будут отличаться на 16-битной платформе от 32/64 (из-за 16-битного инта), третий - на каком-то компиляторе с дефолтным unsigned char (забыл где он, ну это почти экзотика).

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

потому я знаю поведение компиляторов

Так компиляторы разные бывают. Например, во всяких DSP частенько char имеет 16 или 32 бита. Потому что процессор в принципе не умеет 8 битные данные адресовать

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

третий - на каком-то компиляторе с дефолтным unsigned char (забыл где он, ну это почти экзотика).

пробел мб не ASCII ЕМНИП, да и char не обязательно 8 бит…

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

Как показал тот случай все наоборот - важно мнение стандарта и компилятора, а не мнение форумного программиста.

mxfm ★★
()
Ответ на: комментарий от cvs-255

Разве unsigned не делает modulo 2**nbits? Впрочем, до фиксированного integer в стандарте я не дочитал…

UPD: или это с арифметикой?

luke ★★★★★
()
Последнее исправление: luke (всего исправлений: 1)
Ответ на: комментарий от mxfm

Например, вот статья на хабре (https://habr.com/ru/post/592233/).

Программисту важно понимать, что указатели в Си не являются 
низкоуровневыми. Стандарт постарался полностью искоренить какую-
либо связь языка с реальным миром. Даже сравнение указателей, 
ссылающихся на разные объекты, объявлено неопределённым 
поведением (раздел 3.3.8, "Relational operators"): 

Прикольно, я об этом забывал. Этак современный Паскаль более низкоуровневый, хе-хе.

praseodim ★★★★★
()
Ответ на: комментарий от cvs-255

Если развёрнуто.

С одной стороны, видя 0xFFFFFFFF >> 32 хочется видеть 0.

С другой, 32 это 0b10_0000, т.е. нужен ещё один входной бит для операции сдвига. А жадность говорит: «нафиг, сделаем сдвиг только для 0-31 бит и сэкономим N-транзисторов». Появляется такая архитектура (не будем тыкать пальцем).

С третьей компилятор, который ловит любое UB, что бы мокнуть программиста в грязь лицом. (Особый привет clang).

Как следствие, забавная задача с подвохом: написать программу которая маску подсети вида \24 приведёт к виду 255.255.255.0

AlexVR ★★★★★
()

4/5.

И то скорее не потому что хорошо знаю стандарт, а потому что напарывался на все эти проблемы.

Стоит бы повспоминать что там в стандарте говорится, конечно зубрить это бессмысленно.

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

unsigned char на ARM платформах по умолчанию. Никакая не экзотика. :)

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

Вообще, было бы здорово, если бы в стандарте прописали, что если невозможно аппаратно выполнить сдвиг на 32 бита, то надо это реализовать с помощью 2 раз по 16. Итп.

А то кажется 8086 (или какой-то другой из тех времен) вообще только >> 1 аппаратно поддерживал

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

еще может быть веселуха на DSP, где char вполне может быть не 8 бит

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