Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Детская ошибка
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Страницы: 1, 2, 3, 4
scifi
Цитата(aiwa @ May 10 2016, 12:43) *
Я не имею ввиду себя или еще кого-то конкретно. Ожидаемый - с точки зрения формальной логики: если b=~а то-> ~b == а.

Ну вот и хорошо, что не ожидаемый. Может быть, хоть это заставит говнокодера заглянуть в учебник и/или справочник. А то ведь если делать программы, руководствуясь одной лишь формальной логикой, то можно такого наворотить... Всё-таки программирование микроконтроллеров требует чуть более глубокого владения инструментарием.
zltigo
QUOTE (dxp @ May 10 2016, 09:57) *
Беспредметное, безосновательное утверждение.

Увы, но для меня лично основаним является то, что за всю жизнь я ни одной вменяемой программы на питоне не встретил sad.gif. Я понимаю, что мой личный опыт не может претендовать на всеобъемлимость, но тем неменее sad.gif.
QUOTE
но если сравнивать с перлом, то сравнение будет не в пользу последнего.

Прямо противоположного мнения sad.gif. Он базируется на слишком небольшом, но все ЛИЧНОМ опыте копания и ОБИЛЬНОЙ доработки питоновских и перловых текстов.
QUOTE
Понятия не имею, в чём вы. Программа на питоне - это текстовый скрипт. Для исполнения она требует исполняемой среды. Про какие dll речь, мне не ведомо.

Я говорю об откомпилированных в EXE питоновских исходниках.
QUOTE
...пришлось столкнуться с парой образчиков говнокода, отсюда и мнение о языке.

допустим, что мне не повезло, но сам факт говнокодерства на языке, котрый позиционируется, как правильный и не говнокодерский все же о чем то говорит sad.gif
QUOTE
Тут можно напомнить, что на сях легко наговнкодить так, что питонам и не снилось.

С этим спору нет sad.gif.

QUOTE (halfdoom @ May 10 2016, 11:49) *
де-факто существуют две несовместимые версии языка: python2/python3, а так-же наблюдается антагонизм сторонников как первого, так и второго;

И до кучи принципиальное отсутствие стандарта языка sad.gif.
dxp
QUOTE (halfdoom @ May 10 2016, 14:49) *
отвратительный дизайн ООП модели (числа и строки не являются объектами, никуда не годный синтаксис доступа к родительским классам - сравните с C++);

Э-э.., простите, но как вы сравниваете несравнимые вещи? Ответьте для начала на вопрос: что является классом в С++ и что является классом в Питоне? Правильный ответ вам сразу покажет, что вы просто пытаетесь юзать классы Питона точно так же как классы С++. А у них общего только название.

QUOTE (halfdoom @ May 10 2016, 14:49) *
очень медленные треды (из-за кривого дизайна интерпретатора), решается вывертами типа мультипроцессинга;

Треды как треды. Всё обычно для интерпретируемого языка. Или вы его С++ опять сравниваете?

QUOTE (halfdoom @ May 10 2016, 14:49) *
global/nonlocal - это вообще без комментариев;

Тут не понял.

QUOTE (halfdoom @ May 10 2016, 14:49) *
де-факто существуют две несовместимые версии языка: python2/python3, а так-же наблюдается антагонизм сторонников как первого, так и второго;

Насчёт антагонизмов информация устаревшая. В бытность появления тройки, когда она была сырая и глючная, народ плевался, т.к. оные глюки и недоделки мешали работать. Но начиная с версии 3.3+ всё стало пристойно. То, что они отделили развитие, момент спорный, но как показывает практика, решение было скорее правильным, чем не. Можно было и дальше тащить совместимость, как это делает С/C++, обрастая диалектами и поддерживая кривизну исходного дизайна языка, но они решили пофиксить т.н. "бородавки" языка, что привело к некоторой несовместимости. В реальности можно пользоваться и тем, и другим (там немного отличий, на моём уровне так вообще кроме как то, что оператор print сделали функцией, разницы нет), новые вещи лучше писать сразу под тройку.


QUOTE (halfdoom @ May 10 2016, 14:49) *
Мы попытались перенести проект написанный на C++ и убедились, что овчинка совершенно не стоит выделки.

Не очень понял, что вы пытались сделать. Просто тупо переписать код С++ на Питон? Зачем? Какой выигрыш вы ожидали от этого? Работать будет медленнее, это очевидно. Хотели лёгкости модифицирования кода? Но так и код должен быть по-иному организован. Просто тупо портировать С++ код на Питон не получится - ЯП с совершенно другими парадигмами, требует другие подходы, даёт иной выигрыш. Лучшее, что можно было сделать - это внедрить Питон в С++ программу как embedded движок для решения определённого класса задач, если таковые имеются, и которые эффективнее решаются на Питоне.

QUOTE (halfdoom @ May 10 2016, 14:49) *
А вот для скриптов, тест-модулей и прочих несложных программ питон подходит просто идеально, но здесь с ним в конкуренцию вступает Ruby.

Так Питон и есть скриптовый язык. sm.gif Насчёт несложных, это пардоньте, от подхода и целей зависит - очень неслабые приложения на нём пишут и делают это весьма эффективно. Руби - да, конкурент, с Руби Питон можно сравнивать, но не с С++ ни разу. Питон правильно было бы сравнить с языком Матлаба, только Питон шире, гибче и мощнее. Не приходит же в голову сравнивать язык Матлаба с С++ и потом ругать его за то, что плюсовая программа плохо ложится на m-файлы.
halfdoom
Цитата(dxp @ May 10 2016, 15:49) *
Э-э.., простите, но как вы сравниваете несравнимые вещи? Ответьте для начала на вопрос: что является классом в С++ и что является классом в Питоне?


Они вполне сравнимы, отличается реализация, добавляется возможность расширения классов и динамическое разрешение методов, но сути это меняет. Если по смыслу задачи требуется иметь четырехуровневую иерархию, то ее придется реализовать или заменять разными костылями. А далее мы с удовольствием ругаем конструкцию вида super(MyClass, self) или изучение списка self.__class__.__bases__. Кому как, а мне такой подход кажется излишне сложным для скриптового языка. Туда же отнесу и бесконечные self.

Цитата(dxp @ May 10 2016, 15:49) *
Треды как треды. Всё обычно для интерпретируемого языка. Или вы его С++ опять сравниваете?


Да, я сравниваю эффективность реализации. Погуглите про global interpreter lock.

Цитата(dxp @ May 10 2016, 15:49) *
Тут не понял.


Никому не нужные ключевые слова из-за изначально плохо продуманной концепции видимости переменных.

Цитата(dxp @ May 10 2016, 15:49) *
Насчёт антагонизмов информация устаревшая.


Тот факт, что на машине приходится держать оба варианта, говорит сам за себя.

Цитата(dxp @ May 10 2016, 15:49) *
Не очень понял, что вы пытались сделать. Просто тупо переписать код С++ на Питон? Зачем? Какой выигрыш вы ожидали от этого? Работать будет медленнее, это очевидно. Хотели лёгкости модифицирования кода? Но так и код должен быть по-иному организован. Просто тупо портировать С++ код на Питон не получится - ЯП с совершенно другими парадигмами, требует другие подходы, даёт иной выигрыш. Лучшее, что можно было сделать - это внедрить Питон в С++ программу как embedded движок для решения определённого класса задач, если таковые имеются, и которые эффективнее решаются на Питоне.

Как раз и были использованы все преимущества питона как динамического языка. Но этот динамизм и отсутствие возможности задавать типизацию делает верификацию проекта слишком сложной и не эффективной. Когда количество сущностей (классов, если хотите) перевалило за 600, проект был просто закрыт, т.к. человек, поддерживавший его тратил слишком много времени на выявление ошибок и неизбежный рефакторинг. При этом как к питон-программисту к нему претензий нет - более простые вещи нареканий не вызывают.

Цитата(dxp @ May 10 2016, 15:49) *
только Питон шире, гибче и мощнее.


Все это только следствие используемой модели, допускающей динамическое изменение практически всего в процессе работы. Синтаксис и семантика собственно языка не заслуживает положительных эпитетов.
GetSmart
Цитата(zltigo @ May 9 2016, 20:11) *
Они и сейчас так делают.

По-Огурцову и по-Tahoe, Си не обязан ругаться и на это. А если это ругательство норма для Си, то почему на аналогичные ситуации не нужно ругаться, если компилятор их "видит"? Обоснуйте так, чтобы текущая норма не пострадала. У любого компилятора есть неявные обязательства помогать юзеру (в т.ч. замечать ошибки).

По поводу вумного ИАРа, выкинувшего ветвь исходника, топикстартер правильно поднял тему. Отсутствие предупреждения "unreachable code" тянет на недоработку компилятора. Несложно вставить это ругательство в алгоритм компилятора во все места, где удаляется ветвь кода. Конструктивных возражений здесь не видно. Проглядели, вероятно.

На счёт вырождения выражения с переменными или результатами функций в константу ситуация более сложная. В той же неразрывной ветви алгоритма, ранее, могла быть запись константы в переменную. И результат выражения с этой переменной умный компилятор мог бы опознать как константу. Но это вариант нормы Си-кода и на это даже ремарку нет оснований выдавать. В каких-то других случаях замечание компилятора было бы полезным. Но где-то его сообщая, а где-то умалчивая разработчики компилятора могут встретить законное недовольство юзеров. Хотя могут и помочь увидеть кривизну в исходнике.

Цитата
Никакого МОЛЧАНИЯ у IAR, как и других нет, если не не подавлять сообщения.

Это из другой оперы.
Цитата
[Pe068]: integer conversion resulted in a change of sign

Странное сообщение. Для if. Точнее для сравнения (в худшем случае) знакового rvalue и беззнакового.

С инверсией (~, тильда) (не читал стандарт, но судя по этому обсуждению) в стандарте есть кривизна в том, что два раза может происходить расширение операнда. Сперва до int, потом до ширины второго операнда, если он шире. Это немного криво само по себе и из-за разной ширины int на разных платформах. Но если так исторически сложилось, то это уже навсегда. Гарантированную мультиплатформенную совместимость некоторых выражений с тильдой остаётся делать явным приведением.


Цитата(aiwa)
Для полноты картины при бинарных операциях неплохо бы проводить расширение к большему по размеру операнду.

Код
char a;
short b;
long c;

c = ~a & b & c;


Идеально всё-равно не получится. Чуть менее криво или чуть более в таких выражениях. В комбинации с другими операторами будет новая кривизна. Захочется ведь ещё беззнаково расширять.
zltigo
QUOTE (GetSmart @ May 11 2016, 07:40) *
По поводу вумного ИАРа, выкинувшего ветвь исходника, топикстартер правильно поднял тему. Отсутствие предупреждения "unreachable code" тянет на недоработку компилятора.

Для того, что бы "программисту" включить мозг достаточно выдаваемого IAR-ом сообщения:

[Pa091]: operator operates on value promoted to int (with possibly unexpected result)

Пусть думает, как однозначно донести свои думы до компилятора. Более того, это сообщение много информативнее, чем желаемое "unreachable code", ибо указывает на ПРИЧИНУ непонимания, а на следствие.
dxp
QUOTE (halfdoom @ May 10 2016, 22:02) *
Они вполне сравнимы, отличается реализация, добавляется возможность расширения классов и динамическое разрешение методов, но сути это меняет.

К сожалению, я пока вижу недостаточное понимание сути языка и как следствие неверную интерпретацию его средств (попытку использовать их в привычном для другого языка стиле). Давайте вернёмся на первый вопрос: что есть класс в С++ и что есть класс в Питоне? Без ответа хотя бы на этот вопрос остальное обсуждать бессмысленно. Итак:

В С++ класс - это тип, определяемый пользователем.

В Питоне класс - это ...?
halfdoom
Цитата(dxp @ May 11 2016, 09:12) *
В Питоне класс - это ...?


Это просто объект, описывающий структуру данных (включая методы и переменные класса) пригодную для создания экземпляров класса, которые тоже являются объектами.
ViKo
К вопросу о продвижении short. Как пишет Шилдт (стр. 77), и, видимо, стандарт тоже, и подсказывает здравый смысл, в выражениях переменные типов char и short int автоматически продвигаются в int. За все процессоры не скажу, но ARM не имеет операций с байтами или парами байтов, кроме загрузить, расширить знак и сохранить.
aiwa
Цитата(GetSmart @ May 11 2016, 07:40) *
Код
char a;
short b;
long c;

c = ~a & b & c;


Идеально всё-равно не получится. Чуть менее криво или чуть более в таких выражениях. В комбинации с другими операторами будет новая кривизна. Захочется ведь ещё беззнаково расширять.

Идеально, в смысле который Вы имеете ввиду, и не должно получиться.
В силу того, что побитовые логические операции не имеют никакого отношения к знаковости переменной и они не имеют совершенно никакого отношения к арифметике.
Любую побитовую логическую операцию можно рассматривать как набор побитовых операций булевой алгебры между соответствующими разрядами двух операндов.
Грубо говоря двухбйтная переменная в этом случае это не short или unsigned short, а упорядоченный набор 16-ти переменных булевого типа.
Поэтому для бинарных операций разрядное равенство двух операндов строго необходимо, в отличие, теоретически, от команд арифметики.
И тут уже расширение вполне логично с заявленным типом операнда , в противном случае его можно скорректировать явным преобразованием ДО выполнения операции.

А вот унарный оператор ~ стоит особняком: его операнд самодостаточен и совершенно не требует проведения расширения.
Но в отличие от бинарных операций результат работы ~ нельзя скорректировать явным преобразованием ДО выполнения операций - только лишь после.

IgorKossak
Предлагаю участникам сосредоточиться на главном вопросе и не уклоняться в сторону питона.
Модератор.
aiwa
Цитата(ViKo @ May 11 2016, 10:01) *
К вопросу о продвижении short. Как пишет Шилдт (стр. 77), и, видимо, стандарт тоже, и подсказывает здравый смысл, в выражениях переменные типов char и short int автоматически продвигаются в int. За все процессоры не скажу, но ARM не имеет операций с байтами или парами байтов, кроме загрузить, расширить знак и сохранить.

Если обобщить пункты в стандарте, то приводится к первому из списка (int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int) типу,
который в состоянии представить все допустимые значения расширяемого (продвигаемого) типа.
char, short и unsigned short расширяются до знакового int.
halfdoom
Цитата(aiwa @ May 11 2016, 10:45) *
А вот унарный оператор ~ стоит особняком: его операнд самодостаточен и совершенно не требует проведения расширения.


Почему? Ведь это оператор дополнения до единицы, который по совместительству можно использовать для побитовой инверсии.
scifi
Цитата(aiwa @ May 11 2016, 11:05) *
char, short и unsigned short расширяются до знакового int.

За исключением платформ, на которых int 16-разрядный. Там unsigned short должен превратиться в unsigned int. Впрочем, там эти типы отличаются только названием rolleyes.gif
dxp
QUOTE (halfdoom @ May 11 2016, 12:52) *
Это просто объект, описывающий структуру данных (включая методы и переменные класса) пригодную для создания экземпляров класса, которые тоже являются объектами.

В Питоне класс - это динамическое пространство имён. Во всеми вытекающими. Т.е. это никакой не тип, как в плюсах. А все эти наследования и прочее - это средства для управления этими динамическими пространствами имён. Поэтому и семантика классов и взаимоотношения их членов с окружением совершенно иное, чем в С++. Как тут можно сравнивать вообще, я не понимаю.

P.S. Терпение модератора на исходе, поэтому больше офтопить не буду, прошу прощения за неудобства.
aiwa
Цитата(scifi @ May 11 2016, 11:09) *
За исключением платформ, на которых int 16-разрядный. Там unsigned short должен превратиться в unsigned int. Впрочем, там эти типы отличаются только названием rolleyes.gif

Так это и не исключение. Этот случай оговорен формулировкой "к первому из списка, который в состоянии представить все допустимые значения".
Так как int не может представить значения более 32766, то следующим в списке идет unsigned int, который и будет тем "первым, который в состоянии".


Цитата(halfdoom @ May 11 2016, 11:05) *
Почему? Ведь это оператор дополнения до единицы, который по совместительству можно использовать для побитовой инверсии.

Согласен. Но ведь оператор дополнения до единицы тоже в этом смысле самодостаточен.
Хотя, да, возможные нюансы с дополнением я упустил из виду.

Странно, что везде и всюду этот оператор помечен как побитовый логический, в перекор формальному определению стандарта..
scifi
Цитата(aiwa @ May 11 2016, 11:29) *
Странно, что везде и всюду этот оператор помечен как побитовый логический, в перекор формальному определению стандарта..

Вы что-то путаете. Вот определение стандарта:
Цитата
The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type.
ViKo
Цитата(aiwa @ May 11 2016, 11:05) *
Если обобщить пункты в стандарте, то приводится к первому из списка (int, unsigned int, long int, unsigned long int, long long int, or unsigned long long int) типу,
который в состоянии представить все допустимые значения расширяемого (продвигаемого) типа.
char, short и unsigned short расширяются до знакового int.

Если в выражении используются разные типы, тогда действует описанное вами продвижение. Типы же char, short продвигаются, повторюсь, автоматически, независимо от одинаковости или нет типов операндов. Всегда.
aiwa
Цитата(scifi @ May 11 2016, 11:54) *
Вы что-то путаете. Вот определение стандарта:

Цитата
N4582
Date: 2016-03-19
5. Expressions
5.3.1 Unary operators
5.3.1 8).
The operand of the unary - operator shall have arithmetic or unscoped enumeration type and the result
is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The
negative of an unsigned quantity is computed by subtracting its value from 2n, where n is the number of bits
in the promoted operand. The type of the result is the type of the promoted operand.


ViKo
Все (продвинутые) ссылаются на стандарт по языку C. Надо думать, у каждого второго он имеется. Поделитесь, пожалуйста. А то у меня одни черновики.
И на C11, если можно. И на C++14, заодно.
aiwa
Тоже одни черновики.
С системами контроля версий не знаком, поэтому к всеведающим чисто теоретический ворос имеется:
если из репозитария черновиков стандарта (https://github.com/cplusplus/draft) можно сгенерировать текущий черновик,
то можно ли его откатить к последней версии стандарта?
dxp
QUOTE (aiwa @ May 12 2016, 22:01) *
Тоже одни черновики.
С системами контроля версий не знаком, поэтому к всеведающим чисто теоретический ворос имеется:
если из репозитария черновиков стандарта (https://github.com/cplusplus/draft) можно сгенерировать текущий черновик,
то можно ли его откатить к последней версии стандарта?

"Сгенерировать" - неправильный термин, правильнее будет "извлечь из хранилища". Можно извлечь любой комит (фиксацию). Если она не помечена веткой или меткой, то можно посмотреть её "фамилию" - хэш и дать команду

git checkout <hash>

если есть ветка или метка, то

git checkout <branchname>/<tagname>
GetSmart
Шо, привидение увидели?

Цитата(zltigo)
[Pa091]: operator operates on value promoted to int (with possibly unexpected result)
[Pe068]: integer conversion resulted in a change of sign

Не совсем эта, а похожая ругань очень актуальна для умножений по (неудачным) правилам стандарта. Когда расширение должно быть строго с или без знака, как у исходных операндов.
zltigo
QUOTE (GetSmart @ May 17 2016, 04:28) *
Шо, привидение увидели?

?

GetSmart
Цитата(zltigo @ May 17 2016, 09:00) *
?

Сперва они мерились, чей стандарт длиннее.
Потом тишина неприлично затянулась.
Потом кончился попкорн и терпение.

Обсуждение зависло на двух унарных операторах - минусе и тильде.
Цитата
Цитата(aiwa)
А вот унарный оператор ~ стоит особняком: его операнд самодостаточен и совершенно не требует проведения расширения.

Цитата(halfdoom)
Почему? Ведь это оператор дополнения до единицы, который по совместительству можно использовать для побитовой инверсии.

Непонятно, название-то что должно менять? Дополнение до единицы точно так же не арифметическое действие и расширение или заём из старших разрядов не делает.

Моё имхо, с самого начала стандартизации эту пару унарных операторов нужно было выполнять в отложенном режиме. При разборе выражения определив до какого размера придётся "расширяться" операндам. И делать расширение один раз. Но поезд ушёл.
aiwa
Цитата(GetSmart @ May 17 2016, 14:40) *
Непонятно, название-то что должно менять? Дополнение до единицы точно так же не арифметическое действие и расширение или заём из старших разрядов не делает.


Дополнение до единицы является вполне действием одного класса с вычитанием, сложением или умножением, потому что определяется посредством алгебры многочленов.
Называть эти действия арифметическими или еще как - уже не важно.
В этом и состоит коренное отличие от операций булевой алгебры.
Закон жесток, но это закон.




Цитата(GetSmart @ May 17 2016, 14:40) *
Обсуждение зависло на двух унарных операторах - минусе и тильде.

У унарного минуса нет такого эффекта, как у тильды. Дополнительно-расширенные разряды "минуса" лишь подтверждают результат, у тильды же они его меняют.
GetSmart
Цитата(aiwa @ May 17 2016, 17:47) *
Дополнение до единицы является вполне действием одного класса с вычитанием, сложением или умножением, потому что определяется посредством алгебры многочленов.
Называть эти действия арифметическими или еще как - уже не важно.
В этом и состоит коренное отличие от операций булевой алгебры.
Закон жесток, но это закон.

Закон должен быть корректен. Его терминология должна быть практически реализуемой. И соответствовать реализованным в компиляторах действиям. Чтобы не оказалось, что разработчики компиляторов что-то недопоняли. Или недопонимали ранее.

"По словам Майкрософта" и прочих:
Цитата
Оператор дополнения до единицы (~), иногда называемый оператором поразрядного отрицания, дополняет свой операнд до единицы в каждом разряде.

эти два термина - синонимы. В практической реализации, с ограничением ширины операндов.

Приведите какой-либо пример применения тильды, в котором по стандарту она (оператор) не является поразрядной/побитовой инверсией.

По поводу многочленов тоже не ясно. Тильда в Си применяется к целочисленным операндам и результат тоже целочисленный. Как и все остальные до этого обсуждаемые в этой ветке операторы. Предполагаю, что это противоречит терминологии алгебры многочленов.
aiwa
Цитата(GetSmart @ May 17 2016, 17:35) *
Закон должен быть корректен. Его термилогия должна быть практически реализуемой. ....

Должен быть, но на практике не всегда. Одни из важнейших терминов стандарта "lvalue" и "rvalue" вообще не имеют строгого определения и понимаются интуитивно.

Цитата(GetSmart @ May 17 2016, 17:35) *
"По словам Майкрософта" и прочих:........
эти два термина - синонимы. В практической реализации, с ограничением ширины операндов.

Приведите какой-либо пример применения тильды, в котором по стандарту она (оператор) не является поразрядной/побитовой инверсией.

Они синонимы в той же степени как "Наrd disk" и "винчестер". Дают одинаковый результат, вот и считаются синонимами.
Порязрадная инверсия помогает быстро вычислить дополнение, но формально это совершенно разные понятия.
Победил комп с двоичной формой представления чисел, в других системах, например из далекого прошлого, говорить
о поразрядных битовых операциях было бы вообще бессмысленно. Хотя операция дополнения вполне имела бы место.

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

Цитата(GetSmart @ May 17 2016, 17:35) *
По поводу многочленов тоже не ясно. Тильда в Си применяется к целочисленным операндам и результат тоже целочисленный. Как и все остальные до этого обсуждаемые в этой ветке операторы. Предполагаю, что это противоречит терминологии алгебры многочленов.

Способ представления чисел уже основан на алгебре многочленов, ну и, естественно, и операции над ними. Дополнение до двух в этой алгебре необходимо лишь для исполнения операций вычитания - хотя от нас это все скрыто, но формально это так. А для операции тильда в смысле поразрядной логики все это многочленство излишне - достаточно лишь набор инверторов размером с операнд.
GetSmart
Цитата(aiwa @ May 17 2016, 20:43) *
С дополнением искусственный пример придумывать не хочется, сколько себя помню, всегда применял тильду не по стандарту,
а только лишь для поразрядной логики.

Почему искуственный? Нужен пример демонстрирующий принципиальное отличие в рамках языка Си. Или похожего на Си языка программирования. Для демонстрации идеи термина в рамках языков программирования. Название/термин из алгебры многочленов может не весить (значить) ничего (большего, чем побитовая инверсия).

Цитата(aiwa @ May 17 2016, 20:43) *
Должен быть, но на практике не всегда.

В таких случаях неуместно "Закон жесток, но это закон.". Жесток только там и настолько, насколько корректен.

Цитата(aiwa)
Одни из важнейших терминов стандарта "lvalue" и "rvalue" вообще не имеют строгого определения и понимаются интуитивно.

Есть ключевые признаки этих терминов. "Объект с адресом и имеющий значение/содержимое" и "значение/содержимое". Слэш здесь понимается как обобщение. Хотя некоторые значения (булевы) в Си не могут быть содержимым.
aiwa
Цитата(GetSmart @ May 17 2016, 20:05) *
Почему искуственный? Нужен пример демонстрирующий принципиальное отличие в рамках языка Си. Или похожего на Си языка программирования. Для демонстрации идеи термина в рамках языков программирования.

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

Цитата(GetSmart @ May 17 2016, 20:05) *
Название/термин из алгебры многочленов может не весить (значить) ничего (большего, чем побитовая инверсия).

Инверсия битов - это быстрый косвенный способ вычисления дополнения. По аналогии с умножением: мы производим умножение столбиком,
но когда умножаем на 10 то просто дописываем сзади "0", опуская сам процесс умножение.
В системе счисления по основанию 3 дополнение до 3 надо будет вычислять уже по определению дополнения, хотя возможно и будет
более удобный и быстрый косвенный способ как инверсия в двоичной системе.

Цитата(GetSmart @ May 17 2016, 20:05) *
В таких случаях неуместно "Закон жесток, но это закон.". Жесток только там и настолько, насколько корректен.

Он определяет тильду как дополнение. Хотя и называет ее в разных местах по всякому.
Мы можем использовать свойства дополнения быть инверсией как результат порязрядного отрицания, но формально это все же дополнение.
Это кажется тавтологией, но здесь, как и при умножении матриц важны совпадения соразмерностей матриц.
Ведь логическое поразрядное отрицание восьмибитного операнда, по сути, это совокупность восьми логических операций,
а шеснадцатиразрядного - совокупность шестнадцати операций.
Поэтому расширение операнда в трактовке тильды как поразрядного отрицания уже изменяет сам набор операций, в отличие от дополнения
когда операция по сути та же.

Жизни программиста это никак не мешает, надо лишь помнить, что "побитовые операции" - сленг рожденный из-за схожести с настоящими побитовыми операциями.
ViKo
Господа, вы занимаетесь казуистикой. Надо помнить одно - операции выполняются в регистрах (или аккумуляторе), имеющих конкретную длину - integer, и выполняются во всю эту длину, естественно. Это и использовано в стандарте на язык С.
Вот как там у 8-разрядных микроконтроллеров с int дело обстоит? Там, наверное, int8 до int16 или int32 не продвигается?

Нашел. http://ww1.microchip.com/downloads/en/Devi...c/50002053F.pdf
Раздел 5.6.1 Integral Promotion
Продвигается. Уже.
GetSmart
Цитата(aiwa @ May 17 2016, 21:57) *
В системе счисления по основанию 3 дополнение до 3 надо будет вычислять уже по определению дополнения, хотя возможно и будет
более удобный и быстрый косвенный способ как инверсия в двоичной системе.
...
Он определяет тильду как дополнение. Хотя и называет ее в разных местах по всякому.
Мы можем использовать свойства дополнения быть инверсией как результат порязрядного отрицания, но формально это все же дополнение.
Это кажется тавтологией, но здесь, как и при умножении матриц важны совпадения соразмерностей матриц.
...
Жизни программиста это никак не мешает, надо лишь помнить, что "побитовые операции" - сленг рожденный из-за схожести с настоящими побитовыми операциями.

Не тавтологией. Словоблудием. Введением в заблуждение.
В стандарте указано без всяких разночтений, что целочисленные операнды представлены в двоичном коде. Отрицательные числа в двоичном дополнительном коде. Именно это нужно помнить и понимать. С этой базы нагружать оператор нереализуемыми свойствами бессмысленно. Пока в возможностях языка это видится как два названия одного и того же действия. Точнее из терминов/названий будет тот, который не содержит ложных ассоциаций. Кроме того, операция инверсии бит является частью группы логических побитовых/булевых операций и считать этот функционал тильды "работающим по-совместительству" нет оснований. Или можно вполне законно считать, что логические операторы тоже имеют воображаемые свойства из какой-либо ещё алгебры.

Приведённые примеры к языкам, похожим на Си отношения не имеют. Пока всё мимо.

Цитата
Он определяет тильду как дополнение. Хотя и называет ее в разных местах по всякому.

Использование в основном текстовом определении это тоже называние. Это ещё можно толковать как "желательный" вербальный термин, ничем функционально (по действию) не отличающийся от альтернативных названий. Пока нет аргументов утверждать, что тильда в Си это не побитовая инверсия. Аргументом может быть текст на Си, который должен выполнить что-то другое или большее, чем побитовую инверсию. А не словоблудие, в т.ч. в стандарте.
aiwa
Цитата(ViKo @ May 17 2016, 21:18) *
Господа, вы занимаетесь казуистикой. Надо помнить одно - операции выполняются в регистрах (или аккумуляторе), имеющих конкретную длину - integer, и выполняются во всю эту длину, естественно. Это и использовано в стандарте на язык С.

Размер регистра для компилятора алгоритмически не важен: он влияет только на производительность и размер генерируемого кода.
При выполнении большинства арифметических действий такое расширение по умолчанию вполне логично и оправдано: получается более короткий и быстрый код.
Грубо говоря, при этом меняется не размерность операндов (или результата) а размерность средства представления.
От хранения в большей по размеру коробке, хранимая вещь никак не изменится.

Цитата(ViKo @ May 17 2016, 21:18) *
Вот как там у 8-разрядных микроконтроллеров с int дело обстоит? Там, наверное, int8 до int16 или int32 не продвигается?

Не всегда продвигается. Например, я всегда использую char вместо int в качестве счетчика цикла - код получается меньше и быстрее.




Цитата(GetSmart @ May 17 2016, 21:25) *
Кроме того, операция инверсии бит является частью группы логических побитовых/булевых операций и считать этот функционал тильды "работающим по-совместительству" нет оснований. Другого до сих пор не обозначено.


Как раз в стандарте обозначено совершенно другое:
Цитата
The operand of ~ shall have integral or unscoped enumeration type; the result is the ones’ complement of its operand.

Это пункт 5. Unary operators.
Формально тильда не относится к группе логических поразрядных операторов.
И синоним у нее не тот который преподносит мелкософт, а "compl" - сокращение от официального названия операции дополнения.

GetSmart
Цитата(aiwa @ May 18 2016, 05:42) *
Это пункт 5. Unary operators.
Формально тильда не относится к группе логических поразрядных операторов.

Фильтром (всякой чепухи и многозначности) всё-равно являются реализуемые возможности языка.

Приведу пример из суровых российских реалий якобы обхода подобного законодательного формализма производителями ламп накаливания. Выпускающиеся сейчас лампы называют ТЕПЛОНАГРЕВАТЕЛЬ, 200W. Идея обхода в том, что на законодательном уровне не дана совокупность (видимых/измеряемых) признаков, ИДЕНТИФИЦИРУЮЩАЯ лампу накаливания. Дабы закон не зависил от ушлости продавцов и производителей называющийх одну и ту же вещь по-своему. А в стандарте Си требуются определения ОТЛИЧИЙ от побитовой инверсии. Иначе суть написанного есть допустимый вариант называния, а не определение. Доказательством приводите практические отличия на языке (очень похожем на) Си, а не на "описательном" языке.
halfdoom
Цитата(GetSmart @ May 17 2016, 21:25) *
Пока нет аргументов утверждать, что тильда в Си это не побитовая инверсия.


Возможность использования оператора ~ как оператора побитовой инверсии вытекает из определения представления чисел в формате "дополнения до единицы". В C++ данная операция определена так, что инверсия производится после расширения типа до int. ТС успешно прошел по этим граблям, но все, что можно посоветовать в данном случае, это тщательнее читать спецификацию языка или использовать оператор исключающего ИЛИ, который гарантированно определен как побитовый.
ViKo
Если ТС напишет
int8_t temp1 = 0x0001;
if (temp1 ^ (~0) != 0xFFFE)
...
будет то же самое. Продвижение до int.

или так
int8_t temp1 = 0x0001;
int8_t temp3 = 0xFFFF;
if (temp1 ^ temp2 != 0xFFFE)
...
то же. Правда, результат будет тем, которого ждали.
halfdoom
Цитата(ViKo @ May 18 2016, 09:26) *
будет то же самое. Продвижение до int.

или так
int8_t temp1 = 0x0001;
int8_t temp3 = 0xFFFF;
if (temp1 ^ temp2 != 0xFFFE)


Ну а кто заставляет использовать для битовых операций типы со знаком? Используйте беззнаковые и будет вам.
GetSmart
Цитата(halfdoom @ May 18 2016, 09:57) *
Возможность использования оператора ~ как оператора побитовой инверсии вытекает из определения представления чисел в формате "дополнения до единицы".

Это единственная возможность его использования в Си. Не пытайтесь отбиться другим языком, в котором БОЛЬШИНСТВО операторов можно перегружать, т.о. меняя определённый по-умолчанию функционал.
Цитата
В C++ данная операция определена так, что инверсия производится после расширения типа до int. ТС успешно прошел по этим граблям, ...

Расширение общее для многих операторов и определено отдельно от тильды. Грабли тоже мимо.

На уровне фундамента Си, тильда ничего большего побитовой инверсии не делает. Опровергается только выражением НА ЯЗЫКЕ СИ, делающем что-то непохожее на побитовую инверсию. А не словоблудием из описательного языка..
halfdoom
Цитата(GetSmart @ May 18 2016, 10:04) *
Не пытайтесь отбиться другим языком, в котором БОЛЬШИНСТВО операторов можно перегружать, т.о. меняя определённый по-умолчанию функционал.


Я где то упоминал C++ и перегрузку данного оператора?

Цитата(GetSmart @ May 18 2016, 10:04) *
Опровергается только выражением НА ЯЗЫКЕ СИ, делающем что-то непохожее на побитовую инверсию. А не словоблудием из описательного языка..


Пожалуйста:

Код
a = b + ~c;

вычесть из b c представленное в дополнительном коде.
ViKo
Цитата(halfdoom @ May 18 2016, 10:03) *
Ну а кто заставляет использовать для битовых операций типы со знаком? Используйте беззнаковые и будет вам.

Ничего не изменится. Я машинально написал, имея в виду 8-битовые переменные.
GetSmart
Цитата(halfdoom @ May 18 2016, 11:12) *
Код
a = b + ~c;

вычесть из b c представленное в дополнительном коде.

Что не совпадает с побитовой инверсией? Учитывая приоритет расширений операндов и выполнения операций по правилам Си.
В Си и (вероятно) Си++ расширение и выполнение тильды - два отдельных действия. Перемена очерёдности их выполнения сути тильды (по отношению к целочисленным и enum операндам) не меняет.

Для проверки можно сделать замену на другую арифметическую операцию и написать

a = b * ~c;

умножение будет на побитово инвертированную переменную c. Расширенную по правилам Си. Предполагаю, что все три переменные - целочисленные.
halfdoom
Цитата(ViKo @ May 18 2016, 10:20) *
Ничего не изменится. Я машинально написал, имея в виду 8-битовые переменные.


Вы не правы.

Условие (a ^ B) != 0xfffe будет всегда истинным для a и b типа short, но с unsigned short будет работать как ожидается (при sizeof(int) == 4).
aiwa
Цитата(GetSmart @ May 18 2016, 10:30) *
Что не совпадает с побитовой инверсией? Учитывая приоритет расширений операндов и выполнения операций по правилам Си.
В Си и (вероятно) Си++ расширение и выполнение тильды - два отдельных действия. Перемена очерёдности их выполнения сути тильды (по отношению к целочисленным и enum операндам) не меняет.

Для беззнаковых целочисленных в С++ меняет:
при varU16 = 0x0001;
~varU16 и ~((U16)varU16) - сначала расширение, затем тильда - результат один и тот же 0xFFFFFFFE.
((U16)(~varU16) - сначала тильда, затем расширение - результат 0x0000FFFE;
scifi
О господи, бесконечные хождения вокруг трёх битов cranky.gif
Скукотища wacko.gif
GetSmart
Дадада. Переливаю тут из пустого в порожнее.

Результат (воображаемой согласно терминологии) тильды должен быть отличный от выполнения тильды строго как побитовой инверсии. Пока всё мимо.
aiwa
Цитата(GetSmart @ May 18 2016, 12:11) *
Дадада. Переливаю тут из пустого в порожнее.

Результат (воображаемой согласно терминологии) тильды должен быть отличный от выполнения тильды строго как побитовой инверсии. Пока всё мимо.

Почему должен быть различен? Результат как раз гарантировано совпадает, что и является поводом использование операции дополнения в качестве
функции побитовой инверсии.
GetSmart
Цитата(aiwa @ May 18 2016, 16:57) *
Почему должен быть различен? Результат как раз гарантировано совпадает, что и является поводом использование операции дополнения в качестве
функции побитовой инверсии.

Если на витрине лежит что-то, в точности похожее на лампу накаливания, но написано Теплонагреватель, то это лампа? )))

Двадцать постов фанаты стандарта пытались доказать, что название побитовая инверсия неточно. Вроде частного случая. Если же побитовая инверсия единственно возможное действие оператора тильды, то по факту (а не по неудачной терминологии стандарта) это логический поразрядный оператор языка Си. Даже если в стандарте так не написано.

Цитата(aiwa)
В этом и состоит коренное отличие от операций булевой алгебры.
Закон жесток, но это закон.

Коренное отличие до сих пор не обнаружено. Закон нервно курит.
aiwa
Цитата(GetSmart @ May 18 2016, 16:43) *
Двадцать постов фанаты стандарта пытались доказать, что название побитовая инверсия неточно. Вроде частного случая. Если же побитовая инверсия единственно возможное действие оператора тильды, то по факту (а не по неудачной терминологии стандарта) это логический поразрядный оператор языка Си. Даже если в стандарте так не написано.

Как бы не совсем так. В результатах самой операции тильда сомнений не возникает, все вопросы, в принципе, касались насколько верно, а это согласно стандарту,
к операциям логики применять предваряющие правила расширения для арифметики.
Что касается самого стандарта, так в нем не написано что такое побитовые логические операции.

Цитата(GetSmart @ May 18 2016, 16:43) *
Коренное отличие до сих пор не обнаружено. Закон нервно курит.

Коренное отличие совсем не в результате а в расширении.
Первая группа: побитовые логичекие операции над операндами определенного размера
образуют замкнутую структуру (поле): результат выполнения остается той же разрядности.
Правда эту чудесную возможность первой группы операций стандарт не использует, в чем и была суть дискуссии.
Другая групппа: арифметические операции такой структуры не образуют - их результат может выйти за пределы, в чем и состоит неизбежность расширения.
А так как тильда определена как дополнение, то она относится уже ко второй группе и дальнейшие рассуждения о расширении
уже становятся бесперспективными по определению. Идентичность результата совершенно не имеет никакого значания.

Цитата(GetSmart @ May 18 2016, 16:43) *
Если на витрине лежит что-то, в точности похожее на лампу накаливания, но написано Теплонагреватель, то это лампа? )))

Если уж брать аналогию с витриной, она выглядит немного по другому: если некто собирается выкладывать на витрину бутерброды (арифметические операции),
то он может взять поднос немного побольше (аналог расширения), чтобы бутерброды наверняка поместились. Но если ему предстоит наливать вино (побитовые операции),
то лучше бы чтобы размерность тары совпадала с объемом вина.
Сегодняшний стандарт настаивает чтобы вино было налито в тазик - согласно расширению.

Цитата
Им спора не решить... А жаль!
Ведь можно наливать... вино в хрусталь.


GetSmart
Цитата(aiwa @ May 18 2016, 18:58) *
Коренное отличие совсем не в результате а в расширении.
...
Другая групппа: арифметические операции такой структуры не образуют - их результат может выйти за пределы, в чем и состоит неизбежность расширения.
А так как тильда определена как дополнение, то она относится уже ко второй группе и дальнейшие рассуждения о расширении
уже становятся бесперспективными по определению. Идентичность результата совершенно не имеет никакого значания.

Неизбежность? Что, так и написано в скрижалях? ))
Расширение, оно как бы "сбоку" от ВСЕХ операций. У него свои простые правила. Его может не быть (не требоваться), а арифметические переполнения - вариант нормы.

В десятый раз: тильда не определена, а названа. Неудачно. Т.к. по факту действий точнее другое название. И у тильды нет своего особого расширения. Опять всё мимо.
halfdoom
Цитата(GetSmart @ May 18 2016, 16:43) *
Двадцать постов фанаты стандарта пытались доказать, что название побитовая инверсия неточно. Вроде частного случая. Если же побитовая инверсия единственно возможное действие оператора тильды, то по факту (а не по неудачной терминологии стандарта) это логический поразрядный оператор языка Си.

Коренное отличие до сих пор не обнаружено. Закон нервно курит.


Попробуйте предсказать значения следующих выражений (sizeof(int) == 4):
Код
int16_t a, b;
int32_t c, d, e, f;

a = 1;
b = 65534;
c = ~a;
d = ~b;
e = a ^ 0xffff;
f = b ^ 0xffff;


Будет ли c == e и d == f?
Причем заметьте, что две последние строки, это точная побитовая инверсия переменных a и b.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.