К тому же вынужден признать, что и в Intel не та логика, как я писал. Вот их официальная позиция по вопросу использования флага CF:
И они косячники ?
Может надо на SF смотреть ?
Мы тута в беспокойстве !!!
О сколько тебя ждёть открытий чудных в Дао С++. Если раньше в дурдом не попадешь.
У интела же написано “unsigned”. В " баге" никакого переполнения нет - за лимит в 16 бит никто не вылез.
И, да - ардуина не наша, а итальянская. Итальянцы же, как известно, чистые цыгане. А чего от цыган ожидать…
в 32 битах крутится цикл …
С точки зрения компилятора, условие (i <= 32767) всегда true, при любом значении i. И он тебе даже, скорее всего, warning выдал, если они у тебя включены, канеш, обычно крутые VB программисты на какие-то там warning-и внимания не обращают. Поэтому, оптимизатор подумал ЗА тебя, не может же прокладка между креслом и мной быть настока тупой, и расширил переменную цикла до long, вдруг тебя teamlead потом четвертует за неправильный цикл, ай-яй-яй. Оказалось, что может. Напиши ты условие (i < 32767) или (i < 32768) и таких проблем, как у тебя не возникнет. В первом случае цикл в единственном случае будет неравен true, поэтому гадать не надо, компилируем как есть, а во втором будет ошибка переполнения целого, о чём тебя радосно уведомят.
А тут тогда почему иначе - Что за цирк с типом данных int? - #62 от пользователя Komandir ?
Предсказатель отключается. Отключи оптимизатор, проблем в цикле тоже не будет.
ты меня разочаровал )))
Итак, коллеги, начнём.
Исторический экскурс. Не является необходимым для понимания дальнейшего
Когда-то давно, в доисторические времена (с 1981 по 1984), я работал сменным системным программистом в вычислительном центре статуправления томской области. У нас было несколько мощных (по тем временам) машин и программисты из разных организаций города арендовали на них машинное время (чаще по ночам) и считали какие-то свои задачи. В обязанности дежурного системщика входило поддерживать работоспособность системы и консультировать юзеров в случае затыков с системными вещами.
Примерно один-полтора раза в неделю находился деятель, который вваливался без стука в нашу комнату и с порога выдавал ставшую крылатой фразу: «У вас фортран не работает!». Любые попытки объяснить человеку, что фортран не может не работать, натыкались на «Посмотрите, что я написал и что он при этом делает, и скажите мне, что это не баг в компиляторе!».
Смотрели, разбирались. В 100% случаев (ровно в ста – исключений не было ни разу) выяснялось, что проблема была в том, что компилятор, сцуко, делал ровно то, что написано в описании языка и его (компилятора) документации, а не то, что соответствовало «чувству прекрасного» («здравому смыслу», «элементарной логике», и т.п.) пользователя.
Дальше ситуация могла развиваться по-разному. Адекватные люди с первого (на худой конец, со второго) раза понимали, что в подобных случаях надо или читать описание языка, или идти к дежурному системщику с вопросом «Что Я делаю не так?», а не с заявлением «У вас фортран не работает!». Менее адекватные люди, продолжали гнуть свою линию типа «Мне от рождения качество такое досталось – баги в системе обнаруживать». Нашей «терпелки» хватало раза на три, с четвёртого раза, мы уже не просто объясняли товарищу, что он сделал не так, а с удовольствием показывали ему, что не работает не фортран, а его мозги. Иногда они писали на нас жалобы.
Так что, коллеги, как Вы можете видеть, у меня огромный опыт выслушивания заявлений о багах в компиляторе, линкере и вообще в системе. И именно из этого опыта вытекает мой совет ТС всегда искать ошибку у себя, а не у компилятора. Но ТС, к сожалению, на этот совет плюнул. Бывает. Такой опыт у меня тоже есть и не маленький.
Итак начнём с того, что баг компилятора – это когда программа ведёт себя не так, как того требует описание языка программирования. Если же программа ведёт себя в точности так, как требует описание языка, но не так, как хотелось бы программисту, то это баг не компилятора, а программиста. Если кто-то с этим не согласен и считает, что поведение программы должно соответствовать не описанию языка, а его (программиста) «чувству прекрасного», дальше можно не читать. Такая позиция несовместима с программированием, это уже про другое.
Теперь, давайте разбирать данный конкретный случай.
Переменная i
имеет тип int
. Стандарт языка оставляет физический размер переменной типа int
на усмотрение реализации, но при этом требует (§ 6.9.1), чтобы переменная типа int
была «large enough to contain any value in the range [INT_MIN, INT_MAX]». Распечатав эти константы, мы легко убеждаемся, что в данной реализации переменная типа int
может принимать значения в диапазоне [-32768, +32767]
.
Программа написана так, что при i
равном +32767, исполняется операция i++
. По идее, i
после неё должно стать равным +32768, но, переменная типа int
не может иметь такого значения. Таким образом, имеем ситуацию: «во время выполнения операции, результат оказался вне допустимого диапазона для своего типа».
Что в этой ситуации должно происходить? Читаем стандарт языка (§ 8): «If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined».
Осталось выяснить что означает «behavior is undefined», и что в этой ситуации должно происходить.
Опять же, читаем стандарт (§ 3.27): «undefined behavior – behavior for which this document imposes no requirements» и далее там же «Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to …».
Давайте остановимся и чётко уясним две вещи: 1) язык не предъявляет никаких требований к поведению программы в такой ситуации; и 2) «unpredictable results» означает, что результат может быть любым и, каким бы он ни был, это будет соответствовать определению языка.
Таким образом, имеем:
- программист допустил ошибку и вышел за пределы диапазона используемого типа;
- в полном соответствии со стандартом языка, это привело к неопределенному поведению программы с непредсказуемым результатом.
У кого-то ещё остались претензии к компилятору?
Прошу обратить внимание, все цитаты выше взяты не из документации Ардуино и не из документации компилятора GCC. Они взяты из стандарта языка. Вот такой он – язык С++, а не какой-то другой. Если он кому-то не нравится – программируйте на другом языке. Но обвинять компилятор в том, что он точно следует описанию языка, мягко говоря, не умно.
Поэтому, любые ваши фразы, начинающиеся словами «По идее («как я понимаю» / «по логике», и т.п.) компилятор должен был …», являются лишь выражением Вашего личного «понимания прекрасного». Компилятор Вам ничего не должен. Он должен строго соблюдать правила языка, что он и делает в данной ситуации.
Надеюсь, дискуссия о том, чей это баг завершена?
А вот на ассемблере 20 лет назад такого не было! (C)
я об этом уже сказал, только короче
А девки-то какие тогда были! Глянешь бывало, сразу в штанах тесно. А нонешине … рази ж это девки? Тьфу! Смотришь на неё чуть не голую, а хоть бы что шевельнулось.
Я старался каждое слово подтвердить цитатой из официального документа. Но, боюсь, не в коня корм - ТС всё равно прав. Хотя, посмотрим.
Он уже признался что умный байт/слово, которые знают какой тип они представляют и в зависимости от этого что то делают - это его личная хотелка …
если коротко, я правильно понимаю исходя из того, что ТС запрограммировал вечный цикл компилятор выбрал для хранения счётчика максимально возможную переменную с размерностью uint32_t?
Вы опять пытаетесь завести обсуждение в трясину выяснения "как именно было отработано “неопределённое поведение” и какой именно “непредсказуемый результат” получился. Это разговор ни о чём - “неопределённое” и “непредсказуемый” оно и есть “неопределённое” и “непредсказуемый”. Тут не о чем говорить.
Вопрос касается фундаментальных понятий(для меня), по этому , заранее прошу прощения , но всё же спрошу:
Почему тогда в примере с т.н. “переполнением миллис” всё работает надёжно, как часы, хотя там мы тоже выходим за рамки диапазона unsigned long? И нет unpredictable results?
Оно и здесь работало бы четко, если бы переменная i использовалась в цикле еще куда-нибудь кроме вывода в сериал