Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/198: Рейтинг темы: голосов - 198, средняя оценка - 4.90
21 / 19 / 6
Регистрация: 25.11.2017
Сообщений: 708

Что за тип данных uint32_t?

30.07.2019, 22:34. Показов 40480. Ответов 171
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Это без знаковый int, который занимает 32 бита. А вот t, что значит?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.07.2019, 22:34
Ответы с готовыми решениями:

Как побитово скопировать uint32_t в float, минуя при этом выделения uint32_t в оперативную память
Всем привет, недавно заинтересовал такой вопрос ниже. Как ПОБИТОВО скопировать uint32_t в float, минуя при этом выделения uint32_t в...

Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?
Что такое рекурсивный тип данных? Что такое конструкция рекурсивного типа?

Скажите пожалуйста, что это за тип данных?!
int **allocate2D(int rows, int cols) { int **arr2D; int i, j; arr2D = (int**)malloc(rows*sizeof(int*)); for(i=0;...

171
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
16.08.2019, 10:36
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Renji Посмотреть сообщение
//И фиг вы теперь не константную строку формата сюда сунете
Рекомендую почитать что делает модификатор const при объявлении аргументов функции.
Впрочем, даже если бы он делал то, что вы думаете - изредка таки приходится передавать формат из переменной.
Цитата Сообщение от Renji Посмотреть сообщение
Плеваться варнингами это костыль
Ничего подобного. Предупреждение это предупреждение, то есть компилятор не уверен знает ли программист что делает и предлагает подумать над кодом еще. Тем не менее, формально код вполне корректный и для некоторых хаков вполне может применяться.
Цитата Сообщение от Renji Посмотреть сообщение
И вот не надо сказок про наличие контроля типов в Си.
Вы собрать-то свой код пробовали? Очевидно, нет. Попробуйте.
Цитата Сообщение от Renji Посмотреть сообщение
У вас 19 буковок длиннее 22?
file.print (10 букв) против fprintf (7 букв). Опять вытаскиваете значения с потолка?
Цитата Сообщение от Renji Посмотреть сообщение
Я и Перл с Си одной языковой группой назвать могу, вон в Перле даже printf есть.
Да кто бы сомневался! Вы и Си с С++ одним языком называете.
Цитата Сообщение от Renji Посмотреть сообщение
И половина библиотек у них совпадает вплоть до расположения хедера на диске.
Вы про Си-шные библиотеки, которые С++ тащит без изменения? Или про эволюционное наследие С++, которое вынуждает тащить все возможные рудименты?
Цитата Сообщение от Renji Посмотреть сообщение
По кнопкам и светодиодам - делайте ссылки и не морочьте голову. Port&button=port0;. Опять же, если оптимизатор кода не отвалился, ничего там с производительностью не сделается.
Какие ссылки? Свои примеры я из головы писал по типичным случаям.
Вот например семисегментный индикатор. У него есть выводы сегментов A, B, C,...H. Чтобы вывести на него цифру, надо зажечь определенную комбинацию сегментов. Например, для '4' это B, C, F, G. Для ускорения доступа введем ограничение, что все выводы относятся к одному порту (запись значения в порт это 1 инструкция, а запись всех битов независимо - 32 инструкции, иногда это критично). Совсем хорошо было бы расположить сегменты последовательно, скажем, A=PA0, B=PA1, C=PA2 и т.д. но разводку чипа иногда делают достаточно... экзотично. А разводку индикатора делают ...экзотичной... вообще всегда. Поэтому для удобства разводки платы бывает удобно поменять некоторые выводы местами, например, A=PB2, B=PB0, C=PB7 и т.д. Надеюсь, проблема понятна?
Так вот, как дать понять универсальной библиотеке какие именно биты порта соответствуют определенным сегментам.
На практике задача еще сложнее
Во-первых, индикаторы бывают с общим катодом и с общим анодом, то есть включаются либо подачей лог.1 либо лог.0, это тоже хорошо бы сообщить библиотеке.
Во-вторых, семисегментники по отдельности используются редко. Чаще они сдвоенные, строенные, счетверенные и т.д. При этом выводы сегментов А у всех разрядов соединены на одну линию, выводы В - не другую и т.д. А выбор разряда осуществляется выбором общего анода/катода. Собственно для отображения числа используется так называемая динамическая индикация. То есть включаем первый разряд, выставляем число. Ждем какое-то время. Включаем следующий разряд, выставляем число. Снова ждем. И т.д. Таким образом, помимо сегментов надо еще управлять разрядами. Тоже с выбором полярности!
Если интересно, в свое время я эту задачу решил. Могу даже кинуть ссылку, правда она на другой форум, но что-нибудь придумаю. Естественно, код на Си с кучей макросов.

Цитата Сообщение от Renji Посмотреть сообщение
Нет, если у вас висящее на этом порту устройство принимает только однобайтовые команды, тогда конечно не стоит весь этот огород городить.
Хуже! Обычно устройства принимают вообще отдельные биты. Строки (правильнее - массивы) это скорее к периферии относится, вроде SPI или UART.
.
Я смотрю, тема разработки под конроллеры вам не близка. Так может, не стоит продолжать? Мне-то не сложно, но вы рискуете наговорить глупостей, просто по незнанию матчасти.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.08.2019, 11:45
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Рекомендую почитать что делает модификатор const при объявлении аргументов функции.
Рекомендую скомпилировать обе приведенные мной строки и посмотреть, сунется туда char* или нет. Хинт - автоматический каст char*->const char* не сработает, так как на оба варианта есть своя перегрузка.
Что до предупреждений, их наличие зависит от настроек компилятора. И да, я компилировал код "сунь main в printf". Как уже было сказано выше, без pedantic ключа все прекрасно компилируется и запускается.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
file.print (10 букв) против fprintf (7 букв). Опять вытаскиваете значения с потолка?
И file в fprintf передавать не надо, он аргумент с потолка возьмет. Считайте функцию со всеми ее аргументами.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы про Си-шные библиотеки, которые С++ тащит без изменения? Или про эволюционное наследие С++, которое вынуждает тащить все возможные рудименты?
Никто, никого не вынуждает тащить VLA. Его в стандарте C++ вообще нету (хотя, грозились сделать). Тащат потому что реально удобная штука. А говорил я про стащенные целиком сишные библиотеки.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Поэтому для удобства разводки платы бывает удобно поменять некоторые выводы местами, например, A=PB2, B=PB0, C=PB7 и т.д. Надеюсь, проблема понятна?
Вас битовые маски делать научить?
Как написано на каждом заборе, AVR-компилятор отображает порты на восьмибитовые переменные PORTA, PORTB, PORTC... Этой абстракции уже более чем достаточно чтобы свести вашу задачу к PORTB=bitMask, где каждому биту маски соответствует ножка на плате. Задача формирования самой маски никакого отношения к портам уже не имеет.

Когда вы спрашивали про абстракции, я полагал что вам оператора присваивания мало и нужно навесить на порт десяток библиотечных функций. Вот от этого ответ и танцует - пилите объект Port, пихайте в него свои библиотечные функции, если обращаться к объекту напрямую неудобно, делайте ссылки. А если вам надо просто читать-писать единичные биты, ну так дальше дергайте PORTB напрямую.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
16.08.2019, 15:53
Цитата Сообщение от Renji Посмотреть сообщение
Рекомендую скомпилировать обе приведенные мной строки и посмотреть, сунется туда char* или нет.
Еще раз говорю: если уж выдаете свой код в качестве эталона, сначала добейтесь чтобы ваш код просто компилировался без ошибок.
Уже по объявлению void myScanf(char*,...)=delete; видно что они не имеет ни малейшего шанса скомпилироваться.
Цитата Сообщение от Renji Посмотреть сообщение
И да, я компилировал код "сунь main в printf". Как уже было сказано выше, без pedantic ключа все прекрасно компилируется и запускается.
А чего вы ожидали, подсовывая в функцию указатель вместо указателя?
Цитата Сообщение от Renji Посмотреть сообщение
Никто, никого не вынуждает тащить VLA. Его в стандарте C++ вообще нету
Опять вас в какую-то левую сторону несет. Откуда VLA взялось?
Если С++ заявляет совместимость с Си, он вынужден тащить совместимость с Си и всеми библиотеками Си. Ну либо вкручивать эмуляцию, но это уже совсем извращение.
Цитата Сообщение от Renji Посмотреть сообщение
Вас битовые маски делать научить?
Угу, сейчас человек, не знающий ни контроллеров, ни Си, учить будет. Впрочем, поучите, будет забавно. Пример задачи я описал: восемь выводов, произвольно тасуемые между восемью битами. В результате должна получиться библиотека, умеющая выводить одну цифру (задача повышенной сложности - вывод нескольких цифр на многоразрядный индикатор. Задача еще повышенной сложности - индикатор может висеть на разных портах).
выглядеть может, например, так
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define SEG_A B,2,1 //сегмент А на PB2, активный уровень лог.1
#define SEG_B C,0,1
#define SEG_C A,5,1
#define SEG_D B,1,1
#define SEG_E B,0,1
#define SEG_F B,3,1
#define SEG_G B,4,1
#define SEG_H B,5,1
 
#define DIG_0 A,0,0 //разряд 0 на PA0, активный уровень лог.0
#define DIG_1 A,1,0
#define DIG_2 A,2,0
#include "7seg.h" //собственно библиотека. Все что выше - настройки
...
led_out( 123 ); //использование
Не воспринимайте этот кусок буквально, это всего лишь пример из головы. В реальности настройки надо как минимум вынести в файл конфигурации, да и переключения разрядов здесь нет.
Но вот сам принцип именования линий я использую именно в таком виде: порт, бит, уровень
Сразу скажу, макросы по использованию такой записи достаточно неочевидные в написании. Вот в использовании все просто:
C
1
2
3
4
#define LED B,1,1
...
DDR_1( LED ); //переводим порт в режим выхода (push-pull) (разворачивается в DDRB |= (1<<1); )
PORT_ON( LED ); //включаем светодиод (подаем на него активный уровень, он же третий аргумент) (разворачивается в PORTB |= (1<<1);
Теоретически, на С++ и шаблонах возможно написать не менее эффективный код. Не исключаю, что некоторым плюсовикам его будет даже проще читать. Вот остальным программистам - однозначно нет.

Цитата Сообщение от Renji Посмотреть сообщение
Когда вы спрашивали про абстракции, я полагал что вам оператора присваивания мало
О, задач на любые уровни абстракции хватает! Но давайте все же идти последовательно.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.08.2019, 16:51
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Уже по объявлению void myScanf(char*,...)=delete; видно что они не имеет ни малейшего шанса скомпилироваться.
Шел 2019 год. Люди продолжали удивляться конструкциям введенным в C++11. Все прекрасно компилируется. =delete означает "есть такая функция, но вызывать ее нельзя". Можете вместо этого по старинке поставить точку с запятой, а тело не объявлять.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А чего вы ожидали, подсовывая в функцию указатель вместо указателя?
В сигнатуре функции вообще-то, const char* стоит. Ожидал я что при попытке сунуть в printf черт знает что, компиляция грохнется с ошибкой. Получил только варнинг. Да и тот, вообще говоря, отключить можно.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Опять вас в какую-то левую сторону несет. Откуда VLA взялось?
Если С++ заявляет совместимость с Си, он вынужден тащить совместимость с Си и всеми библиотеками Си. Ну либо вкручивать эмуляцию, но это уже совсем извращение.
C++ никакой совместимости ни с кем не заявляет. Заявляют ее авторы gcc, у которых такие фокусы являются расширением языка. Работающим по умолчанию, да.
Ну а VLA взялось из "тащить все возможные рудименты". Извините, "рудиментов" помимо Flexible Array Members и VLA не вспоминается. Ну, разве что еще невозможность копировать массивы.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Пример задачи я описал: восемь выводов, произвольно тасуемые между восемью битами.
Ну я и говорю, маски. На случай когда индикатор висит на разных портах пример сами обобщите?
C++
1
2
3
4
5
6
7
constexpr auto segmentA=1<<6;//Сегмент A на шестом выводе
constexpr auto segmentB=1<<5;//Сегмент B на третьем выводе
constexpr auto invertedMask=(1<<0)|(1<<5);//Выводы 0 и 5 зажигаются нулем
//Семерка состоит из сегментов A и B
constexpr auto sevenMask=(segmentA|segmentB)^invertedMask;
//показываем семерку
void showSeven(){PORTA=sevenMask;}
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
17.08.2019, 01:18
Цитата Сообщение от Renji Посмотреть сообщение
Шел 2019 год. Люди продолжали удивляться конструкциям введенным в C++11.
Шел 2019 год. Люди выдают плюсовый код за сишный.
Цитата Сообщение от Renji Посмотреть сообщение
В сигнатуре функции вообще-то, const char* стоит.
Ну. Указатель. И что?
Цитата Сообщение от Renji Посмотреть сообщение
Ожидал я что при попытке сунуть в printf черт знает что, компиляция грохнется с ошибкой. Получил только варнинг. Да и тот, вообще говоря, отключить можно.
То есть типичный Си-шный подход, где вся ответственность лежит на программисте, для вас в диковинку. Ну так чего лезть в незнакомую тему со своими извращенными представлениями?!
Компилятор не будет мешать вам выстрелить себе в ногу. Максимум - предупредит, что это опасно. Но если вы ему прямым текстом сказали "стреляй!" - он выполнит.
Цитата Сообщение от Renji Посмотреть сообщение
C++ никакой совместимости ни с кем не заявляет. Заявляют ее авторы gcc
То есть то, что в большинстве компиляторов С++ компилируется почти любой Си-шный код виноваты не стандарт, не разработчики компиляторов, а только gcc? А плюсовики в курсе?
Цитата Сообщение от Renji Посмотреть сообщение
Ну а VLA взялось из "тащить все возможные рудименты". Извините, "рудиментов" помимо Flexible Array Members и VLA не вспоминается. Ну, разве что еще невозможность копировать массивы.
Нет, под рудиментами для С++ я имел в виду почти весь Си-шный синтаксис, ведь он плохо соответствует современной идеологии С++ и оставлен только для совместимости.
Вот в Си он активно используется и вписывается в идеологию, поэтому там рудиментом не является.
Цитата Сообщение от Renji Посмотреть сообщение
Ну я и говорю, маски. На случай когда индикатор висит на разных портах пример сами обобщите?
Да я пока и для одного порта обобщить по-человечески, без оверхеда не могу. Вы предлагаете писать по одной функции для каждой цифры что ли?! А выбирать их switch'ем, да? Ну и в семерке, вообще-то, три сегмента горят: A, B и C: верхний и два правых.
Еще в вашем примере явное дублирование настроек плюс ошибка копипаста: объявляете сегменты на 5 и 6, а маску на 0 и 5, причем в другом месте.
Хорошо, для примера код вывода любой цифры. На макросах, естественно:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//настройки
#define SEG_PORT PORTB
#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DOT 7
#define SEG_POL 1
 
void led7_show( uint8_t num );
 
//внутренняя рганизация библиотеки
#if (SEG_POL )
  #define _SEG_POL(x) (x)
#else
  #define _SEL_POL(x) (~(x))
#endif
const uint8_t seg_codes[]={
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_E) | (1<<SEG_F)), //0
  _SEG_POL((1<<SEG_B) | (1<<SEG_C)), //1
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_D) | (1<<SEG_E) | (1<<SEG_G)), //2
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_G)), //3
  _SEG_POL((1<<SEG_B) | (1<<SEG_C) | (1<<SEG_F) | (1<<SEG_G)), //4
  _SEG_POL((1<<SEG_A) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_F) | (1<<SEG_G)), //5
  _SEG_POL((1<<SEG_A) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_E) | (1<<SEG_F) | (1<<SEG_G)), //6
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_C)), //7
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_E) | (1<<SEG_F) | (1<<SEG_G)), //8
  _SEG_POL((1<<SEG_A) | (1<<SEG_B) | (1<<SEG_C) | (1<<SEG_D) | (1<<SEG_F) | (1<<SEG_G)) //9
};
 
void led7_show( uint8_t num ){
  SEG_PORT = seg_codes[ num ];
}
Писал из головы, так что мелкие опечатки вполне возможны. Объем занимаемой памяти у такого кода составляет 10 байт, скорость для лучшего случая 7 тактов, для худшего - 13 тактов (без учета собственно вызова):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
led7_show:
  push ZH ;2 такта (в случае инлайна этот регистр скорее всего будет свободен и его можно не сохранять)
  push ZL ;+2 = 4 такта (этот тоже. То есть -4 такта на сохранение и -2 на восстановление)
  ldi ZH, high( seg_codes ) ;+1 = 5 тактов
  ldi ZL, low( seg_codes ) ;+1 = 6 тактов
  add ZL, r24 ;+1 = 7 тактов
  adc ZH, r1 ;+1 = 8 тактов
  ld r24, Z ;+2 = 10 тактов
  out PORTB, r24 ;+1 = 11 тактов
  pop ZL ;+1 = 12 тактов
  pop ZH ;+1 = 13 тактов
ret

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

Добавлено через 14 минут
P.S. Ладно спор на счет классификации языков: это классический спор о вкусе фломастеров. Ладно спор о традициях именования типов и функций в Си (ну хз, вроде все факты на лицо. Уж насколько использование подобных сокращений удобно или хотя бы оправдано - другой вопрос). Я даже могу понять упорство в отстаивании позиции "С++ лучше Си" (хотя этот спор как бы не в тему).
Но вам действительно интересно спорить по поводу программирования контроллеров? Причем не имея опыта в этой области, исходя только из общих соображений. Нет, если действительно интересно, и вы таким образом узнаете что-то новое (я тоже так иногда делаю) то это можно только поддерживать. Если же это спор ради спора, то лучше все-таки прекратить.
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
17.08.2019, 01:32
COKPOWEHEU, думаю, на C++ можно без проблем добиться такого синтаксиса и asm-код будет аналогичным:

C++
1
2
3
4
5
6
7
8
9
constexpr SegmentCodes seg_codes{
    SegCode<SEG_POL, SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F>::value,//1
    SegCode<SEG_POL, SEG_B, SEG_C>::value,//2
    //...
};
 
void led7_show( uint8_t num ){
  SEG_PORT = seg_codes[ num ];
}
Всю генерацию (1 << SHIFT) | (...) и ~(x) возьмут на себя шаблоны.
В результате будет такой же массив с теми же кодами.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,416
17.08.2019, 01:39
Цитата Сообщение от Renji Посмотреть сообщение
C++ никакой совместимости ни с кем не заявляет. Заявляют ее авторы gcc, у которых такие фокусы являются расширением языка.
Эти расширения, однако, имеют лишь поверхностные синтаксическое сходства с соответствующими фичами языка С. GCC-шные VLA-расширения в C++ ведут себя не так, как стандартные VLA в С. Аналогично, GCC-шные compound literals в C++ ведут себя не так, как стандартные compound literals в С.

Поэтому на самом деле говорить о точной совместимости не приходится.

P.S. Что интересно, Clang в C++ пытается реализовывать полноценные С-шные VLA. То есть в С++ коде VLA-расширения ведут себя по-разному в Clang и в GCC.
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
17.08.2019, 02:05
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
написать более понятный код без существенной потери быстродействия?
для вашего кода и для кода ниже gcc генерирует одинаковый asm-код.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//Настройки
//из Вашего кода можно скопипастить
//они не так существенны
 
//Чуть шаблонов
template<uint8_t ... Seg>
inline constexpr uint8_t CombineFlags = ((1 << Seg) | ...);
 
template<uint8_t ... Seg>
inline constexpr uint8_t SegPolCode = CombineFlags<Seg...>;
 
template<uint8_t ... Seg>
inline constexpr uint8_t SegNegCode = ~CombineFlags<Seg...>;
 
template<uint8_t ... Seg>
inline constexpr uint8_t SegCode = SEG_POL? SegPolCode<Seg...>: SegNegCode<Seg...>;
 
//А это выглядит уже лучше:
const uint8_t seg_codes[]={
  SegCode<SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F>, //0
  SegCode<SEG_B, SEG_C>, //1
  SegCode<SEG_A, SEG_B, SEG_D, SEG_E, SEG_G>, //2
  SegCode<SEG_A, SEG_B, SEG_C, SEG_D, SEG_G>, //3
  SegCode<SEG_B, SEG_C, SEG_F, SEG_G>, //4
  SegCode<SEG_A, SEG_C, SEG_D, SEG_F, SEG_G>, //5
  SegCode<SEG_A, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G>, //6
  SegCode<SEG_A, SEG_B, SEG_C>, //7
  SegCode<SEG_A, SEG_B, SEG_C, SEG_D, SEG_E, SEG_F, SEG_G>, //8
  SegCode<SEG_A, SEG_B, SEG_C, SEG_D, SEG_F, SEG_G>, //9
};
 
void led7_show( uint8_t num ){
  SEG_PORT = seg_codes[ num ];
}
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
17.08.2019, 02:27
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Шел 2019 год. Люди выдают плюсовый код за сишный.
Извините, лень вспоминать как перегрузка делается на Generic. Это суть как-то меняет? Попытки использовать char* как строку формата, легко отсекаются на стадии компиляции. Отсекаются ошибкой компиляции, а не варнингом. Но Си этого не делает. Очевидно, потому что уже есть гора кода полагающегося на то что что угодно, можно совать куда угодно, забив на контроль типов.

И да, про то что в Си якобы есть контроль типов заливал отнюдь не я. Теперь пошли на попятную "ну да, можно double* в const char* совать, без явного каста типов. Но это не баг, а фича"?
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
То есть то, что в большинстве компиляторов С++ компилируется почти любой Си-шный код виноваты не стандарт, не разработчики компиляторов, а только gcc? А плюсовики в курсе?
Конечно, в курсе. И долго жаловались на Visual Studio не желавший поддерживать сишный VLA. Допускаю что все подряд из Си тащит не только gcc, но суть не меняется - тащить или не тащить решает автор компилятора.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Нет, под рудиментами для С++ я имел в виду почти весь Си-шный синтаксис, ведь он плохо соответствует современной идеологии С++ и оставлен только для совместимости.
Это не рудименты. Это инструменты для реализации этой самой идеологии. Потроха новомодного std::vector неизбежно будут завернуты на сишный malloc или его аналоги.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Да я пока и для одного порта обобщить по-человечески, без оверхеда не могу. Вы предлагаете писать по одной функции для каждой цифры что ли?! А выбирать их switch'ем, да?
Мне просто лень в Proof of concept демонстрирующий работу с битовыми масками, пихать массив из десяти масок.
Ассемблерный код оценил. 11 тактов из 13 уходят на "инлайн для слабаков". 10 байт памяти уходят на "атрибут PROGMEM для слабаков". Выкидываем массив в RO флеш, инлайним функцию и не морочим голову.

Добавлено через 4 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Поэтому на самом деле говорить о точной совместимости не приходится.
Ну, даже если совместимость и не полная, большая часть кода все же запускается. То что процентов 10 не запускается, это уже различие уровня "два диалекта одного языка".
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
17.08.2019, 10:16
Цитата Сообщение от Croessmah Посмотреть сообщение
для вашего кода и для кода ниже gcc генерирует одинаковый asm-код.
Вы считаете этот код более читаемым?
Цитата Сообщение от Renji Посмотреть сообщение
Извините, лень вспоминать как перегрузка делается на Generic. Это суть как-то меняет?
Понятия не имею. Но пока вы не привели корректного примера, демонстрирующего ошибку, говорить не о чем.
Цитата Сообщение от Renji Посмотреть сообщение
И да, про то что в Си якобы есть контроль типов заливал отнюдь не я. Теперь пошли на попятную
Еще раз: то, что вместо указателя можно подсунуть указатель, которые по сути своей все одинаковые? Противоречие-то где?
Цитата Сообщение от Renji Посмотреть сообщение
Допускаю что все подряд из Си тащит не только gcc
"допускаю, что все подряд из Си тащит gnu compiler C". Для вас откровение, что компилятор Си тащит совместимость с Си?! Если же имелось в виду g++ или все семейство gcc, высказывание не станет разумнее: С++ тащит значительную совместимость на уровне стандарта, а не конкретной реализации. То, что кто-то, возможно (я не проверял и не собираюсь), плакался о поддержке того или иного расширения - ну значит понравилось. Интересная тенденция, кстати: расширения gnu считают полезными и плачутся о поддержке, а какие-нибудь scanf_s - мусором. Новые фишки из Си (хотя казалось бы, сколько их там) тащат в С++, а наоборот - не очень (хотя объявления переменных и комментарии в свое время утащили).
Цитата Сообщение от Renji Посмотреть сообщение
Это не рудименты.
Сырые Си-шные указатели, прямое приведение типов, *alloc'и, представление строк. Все это в С++ помечено как нерекомендуемое и всему этому есть замены. Но вот с концами не выпиливают.
Цитата Сообщение от Renji Посмотреть сообщение
Мне просто лень в Proof of concept демонстрирующий работу с битовыми масками, пихать массив из десяти масок.
Ваш "proof of concept" не демонстрирует пока ничего.
Цитата Сообщение от Renji Посмотреть сообщение
Ассемблерный код оценил. 11 тактов из 13 уходят на "инлайн для слабаков".
Ну не позорьтесь, пожалуйста! Я правда не хочу издеваться над вами, тыкая носом в дурацкие ошибки.
Из 13 тактов 6 уходит на сохранение-восстановление регистров если инлайн по какой-то причине невозможен (это же прямым текстом написано было). Еще 4 такта - на вычисление адреса (какой смысл писать функцию, умеющую выводить только одну цифру, где и кому это может понадобиться?!). Еще 2 - чтение из ОЗУ в регистр (если использовать PROGMEM, инструкция ld заменится на lpm и станет на 1 такт длиннее) и 1 на вывод в регистр.
Цитата Сообщение от Renji Посмотреть сообщение
То что процентов 10 не запускается, это уже различие уровня "два диалекта одного языка".
Когда 90% одного языка не компилируется вторым - это не диалекты. А вот ассемблерный код при помощи вставок компилируется точно. Вывод Renji: ассемблер - диалект Си.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
17.08.2019, 11:54
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Понятия не имею. Но пока вы не привели корректного примера, демонстрирующего ошибку, говорить не о чем.
Еще раз. sscanf("%s",text). Почему вторым аргументом нельзя пихать строку задаваемую на стадии исполнения я, надеюсь, объяснять не надо? Но она туда впихнется. Туда даже число впихнется, хотя оно не имеет никакого отношения к прописанному в сигнатуре const char*.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Еще раз: то, что вместо указателя можно подсунуть указатель, которые по сути своей все одинаковые? Противоречие-то где?
Вам про alignment requirement, strict aliasing и строковые литералы в RO памяти рассказать чтоль?
Как уже указывали выше, противоречие в том что стандарт Си запрещает Implicit conversions const char*->int*. Только, сишный компилятор по умолчанию игнорирует сишный же стандарт. И прекрасно кушает даже преобразования 123->указатель. Воистину, чудесен язык, носителям которого требуется подобное.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
"допускаю, что все подряд из Си тащит gnu compiler C". Для вас откровение, что компилятор Си тащит совместимость с Си?!
Вот когда он в режиме pedantic будет совместим, тогда ой.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Еще 4 такта - на вычисление адреса (какой смысл писать функцию, умеющую выводить только одну цифру, где и кому это может понадобиться?!).
Наверно, может понадобиться в альтернативном решении "Вот как надо! И без масок ваших". Потому как я слабо себе представляю какая тут альтернатива массиву с масками, помимо switch с теми же самыми масками. И я еще раз спрашиваю, оптимизация кода работает или все как всегда?

Делать ldi ZH, high( seg_codes ) по каждому чиху не нужно. Компилятор должен стремиться один раз сохранить адрес в регистр (их же там целых 32).
Делать adc ZH, r1 тем более не нужно. Выровняйте адрес на 8 байт и никаких переносов в старший разряд не будет. (Что будет если к ZL прибавят больше восьмерки? Выход за границы массива и UB).
Ну ок, три такта на все про все. Суть то не меняется - оптимизацию кода включать надо.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Когда 90% одного языка не компилируется вторым - это не диалекты. А вот ассемблерный код при помощи вставок компилируется точно.
И еще раз повторяю, стандарта Ассемблера не существует, а потому ассемблерный код не обязан компилироваться даже при переносе с одного компилятора ассемблера на другой. А вот стандарт на Си и плюсы существует. И во многом совпадает.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
17.08.2019, 14:10
Цитата Сообщение от Renji Посмотреть сообщение
Почему вторым аргументом нельзя пихать строку задаваемую на стадии исполнения я, надеюсь, объяснять не надо?
Ну разумеется, надо. Если уж вы выдвигаете неочевидное утверждение, будьте добры обосновать его! Не просто почему задавать форматную строку из переменной может быть опасно, а почему нельзя ни в коем случае.
Цитата Сообщение от Renji Посмотреть сообщение
Вам про alignment requirement, strict aliasing и строковые литералы в RO памяти рассказать чтоль?
Пожалуйста, прежде чем вводить в спор новые сущности начинайте с аргументации, какое отношение они имеют к заявленной теме. В данном случае, к длине имен стандартных типов и функций в Си.
Цитата Сообщение от Renji Посмотреть сообщение
И прекрасно кушает даже преобразования 123->указатель. Воистину, чудесен язык, носителям которого требуется подобное.
Можете предложить более удобный способ записи в память по фиксированному адресу?
Цитата Сообщение от Renji Посмотреть сообщение
Вот когда он в режиме pedantic будет совместим, тогда ой.
Что-то у меня пока не возникало проблем совместимости gnu-того компилятора Си со стандартом. Что за экзотику вы там собираете?!
Цитата Сообщение от Renji Посмотреть сообщение
Потому как я слабо себе представляю какая тут альтернатива массиву с масками, помимо switch с теми же самыми масками.
Я предложил написать решение вполне стандартной задачи средствами С++. Свое решение средствами Си я привел.
Цитата Сообщение от Renji Посмотреть сообщение
И я еще раз спрашиваю, оптимизация кода работает или все как всегда?
Да какая разница, если мы обсуждаем общий случай! Считайте, что оптимизация работает идеально в пределах стандарта и логики компиляторов. То есть если функция объявлена в одной единице трансляции, она не может оптимизироваться под другую, например.
Цитата Сообщение от Renji Посмотреть сообщение
Компилятор должен стремиться один раз сохранить адрес в регистр (их же там целых 32).
Вообще-то, всего 3: r26:r27, r28:r29 и r30:r31. Сюрприз? А массивов и тому подобного может использоваться куда больше.
Плюс подобные функции часто встраивают в прерывания, где компилятор не имеет права полагаться на какие-либо регистры.
Цитата Сообщение от Renji Посмотреть сообщение
Выровняйте адрес на 8 байт и никаких переносов в старший разряд не будет. (Что будет если к ZL прибавят больше восьмерки? Выход за границы массива и UB).
Откуда взялась восьмерка, если размер массива 10 байт? Я бы еще понял предложение разместить массив в диапазоне 0x0100 - 0x01F5, и то странное решение.
Цитата Сообщение от Renji Посмотреть сообщение
И еще раз повторяю, стандарта Ассемблера не существует
О каком из компиляторов и каком из диалектов вы говорите? Что понимаете под стандартом ассемблера? Общий принцип написания инструкций, констант, макросов и т.п.? Конкретные наборы инструкций и регистров? Соглашения по разработке?
Цитата Сообщение от Renji Посмотреть сообщение
А вот стандарт на Си и плюсы существует. И во многом совпадает.
И уже десять раз было сказано: совместимость и наследство. Причем только в одну сторону.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
17.08.2019, 16:23
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну разумеется, надо. Если уж вы выдвигаете неочевидное утверждение, будьте добры обосновать его! Не просто почему задавать форматную строку из переменной может быть опасно, а почему нельзя ни в коем случае.
Потому что в 99% случаев это будет опечатка и последующий удар граблями по лбу. Для оставшегося 1% есть явный каст (const char*)format.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Пожалуйста, прежде чем вводить в спор новые сущности начинайте с аргументации, какое отношение они имеют к заявленной теме. В данном случае, к длине имен стандартных типов и функций в Си.
Они имеют отношение к вашему утверждению про то что все указатели по сути одинаковые. По стандарту нет, не одинаковые. По свежим стандартам попытка записать данные по *doubleValue и прочитать их обратно по *intValue ведет к UB. Другой вопрос, что сишники конечно же не будут переписывать свои легаси-библиотеки под новый стандарт, так что gcc дальше будет на этот стандарт забивать.

Возвращаясь к теме - чтобы перепутать scanf и sscanf достаточно банальной опечатки. Нормальные люди вводят в код ограничения, от опечаток страхующие. Например, "называйте функцию str_scanf". Сишникам же вместо этого отключают даже те ограничения, которые в их же стандарте и прописаны. Например, запрет неявного каста double*->int*. Ну и что это, если не банальное ретроградство?
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что-то у меня пока не возникало проблем совместимости gnu-того компилятора Си со стандартом. Что за экзотику вы там собираете?!
gcc - комбайн поддерживающий целую пачку языков. И разговор не о том, что в число этих языков входит Си, а о том, что поддержка Си тащится в компиляцию C++ файлов. Что является личной прихотью авторов конкретного компилятора.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Я предложил написать решение вполне стандартной задачи средствами С++. Свое решение средствами Си я привел.
Вы предложили применить к порту какую-то абстракцию. Нет, я конечно же могу приделать сюда шаблоны, которые будут явно удобнее вашего решения. По крайней мере, для случая "надо раскидать индикатор на несколько ножек". Только это уже будет абстракция примененная к конфигам.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//биты маски 0-7 - биты PORTA. 8-15 - PORTB 16-23 - PORTC 24-31 - PORTD
constexpr auto segmentA=1;//нулевая ножка PORTA
constexpr auto segmentB=1<<20;//пятая ножка PORTC
 
//маска со всеми нужными ножками
constexpr auto usedPorts=0xFF00FF;
 
template<unsigned portID>
unsigned getNumberMask(unsigned number)
{
    constexpr auto shift=portID*8;
    //маски для цифр
    static const unsigned numberList[10]={(segmentA>>shift)&0xFF,//да, да, на ноль не похоже. Лень все сегменты вбивать
                                          (segmentB>>shift)&0xFF,
                                          (3>>shift)&0xFF,
                                          (4>>shift)&0xFF,
                                          (5>>shift)&0xFF,
                                          (6>>shift)&0xFF,
                                          (7>>shift)&0xFF,
                                          (8>>shift)&0xFF,
                                          (9>>shift)&0xFF,
                                          (10>>shift)&0xFF};
    return numberList[number];
}
 
void showNumber(unsigned number)
{
    //if-ы раскрываются на стадии компиляции
    if(usedPorts&0xFF)
        PORTA=getNumberMask<0>(number);
    if(usedPorts&0xFF00)
        PORTB=getNumberMask<1>(number);
    if(usedPorts&0xFF0000)
        PORTC=getNumberMask<2>(number);
    if(usedPorts&0xFF000000)
        PORTD=getNumberMask<3>(number);
}
По регистрам - я даже в документацию ATmega8 заглянул, там 32 регистра. И никаких следов того что mov гвоздями прибили к каким-то трем.
По восьмерке - в голове перепутались семь сегментов и десять цифр. Ок, поправка, выравнивание на 16 байт.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
О каком из компиляторов и каком из диалектов вы говорите? Что понимаете под стандартом ассемблера? Общий принцип написания инструкций, констант, макросов и т.п.? Конкретные наборы инструкций и регистров? Соглашения по разработке?
Под стандартом я понимаю тоже самое что в случае C/C++ - талмуд описывающий весь синтаксис языка.
И уже десять раз было сказано: совместимости ни в ту, ни в другую сторону никто не обещал. Более-менее работающая совместимость это личная блажь авторов gcc.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
17.08.2019, 18:41
Цитата Сообщение от Renji Посмотреть сообщение
Возвращаясь к теме - чтобы перепутать scanf и sscanf достаточно банальной опечатки.
Я уже спрашивал, что у вас со зрением если эти две функции путаете. Вот никто не путает, а вы - путаете.
Цитата Сообщение от Renji Посмотреть сообщение
Например, "называйте функцию str_scanf"
А лучше - std::library::string_scan_format, угу.
Цитата Сообщение от Renji Посмотреть сообщение
gcc - комбайн поддерживающий целую пачку языков.
gcc в первую очередь это именно компилятор Си. g++ - компилятор С++. Если же имеете в виду семейство компиляторов - так и говорите.
Цитата Сообщение от Renji Посмотреть сообщение
поддержка Си тащится в компиляцию C++ файлов. Что является личной прихотью авторов конкретного компилятора.
То есть наличие в стандарте С++ сырых указателей, структур, ASCIIZ строк и т.п. является прихотью авторов g++? Услышь я подобное высказывание от кого-то другого - наверное удивился бы. От вас - уже норма.
Цитата Сообщение от Renji Посмотреть сообщение
Нет, я конечно же могу приделать сюда шаблоны, которые будут явно удобнее вашего решения.
Удобнее в плане настроек? Не верю.
Цитата Сообщение от Renji Посмотреть сообщение
constexpr auto segmentB=1<<20;//пятая ножка PORTC
Оно часом не сломается на какой-нибудь ATmega640 у которой порты нумеруются аж до буквы L (целых 80 битов)
Цитата Сообщение от Renji Посмотреть сообщение
if(usedPorts&0xFF) PORTA=getNumberMask<0>(number);
if(usedPorts&0xFF00) PORTB=getNumberMask<1>(number);
Вот такое использование шаблонов заставляет усомниться сумеет ли компилятор не нагенерировать все варианты. Ну да ладно, я же сам сказал что считаем компилятор идеальным. Все равно ваш вариант даже после допиливания использовать невозможно будет.
Цитата Сообщение от Renji Посмотреть сообщение
template<unsigned portID>
Вы сюда добавили шаблоны просто ради шаблонов? На макросах оно нагляднее получается.
Цитата Сообщение от Renji Посмотреть сообщение
По регистрам - я даже в документацию ATmega8 заглянул, там 32 регистра. И никаких следов того что mov гвоздями прибили к каким-то трем.
Я не просто так перечислил регистры, через которые идет обращение к памяти. ld/st/lpm работают только с ними.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
17.08.2019, 19:46
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Я уже спрашивал, что у вас со зрением если эти две функции путаете. Вот никто не путает, а вы - путаете.
Со зрением у меня ровно тоже самое что и у тех, кто ввел конструкции вида int var=1234. Можно же было короче - var=1234. Если var не объявлена, var=1234 объявляет новую переменную. Если объявлена, то перезаписывает переменную. А то что кто-то случайно может настучать vvar=1234, ну так пусть очки купит.

Ну вот только не надо заливать что сишники ни разу не искали в своем коде опечатку в одну букву. Плюсовики искали, перловцы искали, одни сишники никогда опечаток не делают.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
То есть наличие в стандарте С++ сырых указателей, структур, ASCIIZ строк и т.п. является прихотью авторов g++?
Это к совместимости никакого отношения не имеет.
Структуры нужны чтоб не писать class{public:.
Сырые указатели нужны для реализации потрохов умных. Без них придется все в компилятор захардкорить.
Собственно, и VLA пытаются утащить по соображениям удобства плюсовиков. Но пока не утащили, его поддержка - блажь конкретного компилятора.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вы сюда добавили шаблоны просто ради шаблонов? На макросах оно нагляднее получается.
Ради массива с 8-битовыми масками.
Разжевано. Каждая цифра кодируется 32-битовой маской. Реально в моем примере используются только 16 бит соответствующих PORTA и PORTC. То есть, половина маски не используется. Поэтому, маска пилится на четыре байта, которые распихиваются по отдельным массивам. Потом приходит компилятор, говорит "массивом для PORTB никто не пользуется" и выкидывает его. Экономия!

А вот как вы тоже самое провернете на макросах я слабо себе представляю. Разве что ручками будете объявлять четыре практически идентичных массива.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Я не просто так перечислил регистры, через которые идет обращение к памяти. ld/st/lpm работают только с ними.
Вас кто-то дизинформировал. RAMPX, RAMPY, RAMPZ нужны только чтобы вылезти за пределы текущего 64-килобайтового сегмента. Для 16-битовых адресов которые использует ваш код, можно использовать любой регистр. Вот, смотрим в доку и видим там ld r2,X.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
18.08.2019, 09:31
Цитата Сообщение от Renji Посмотреть сообщение
Можно же было короче - var=1234
Так сделано в каком-нибудь Бейсике. Да и в С++ есть auto, которое делает нечто подобное.
Цитата Сообщение от Renji Посмотреть сообщение
А то что кто-то случайно может настучать vvar=1234, ну так пусть очки купит.
Если кто-то настучит var и sdkljgnslkntv, а потом умудрится их перепутать - тут даже очки не помогут.
Цитата Сообщение от Renji Посмотреть сообщение
Ну вот только не надо заливать что сишники ни разу не искали в своем коде опечатку в одну букву
В именах своих переменных, называемых var1, var2, в индексах цикла i->j - это сколько угодно. Но вот чтобы printf перепутать с sprintf - такого не видел.
Цитата Сообщение от Renji Посмотреть сообщение
Структуры нужны чтоб не писать class{public:.
Ничего подобного. Структуры в С++ это лишняя сущность, которая должна бы реализовываться через класс, но ради совместимости с Си решили протащить в неизменном виде. А чтобы не было нужды писать class{public: достаточно было сделать поля по дефолту публичными.
Цитата Сообщение от Renji Посмотреть сообщение
Сырые указатели нужны для реализации потрохов умных. Без них придется все в компилятор захардкорить.
Ну так захардкодили бы, в чем проблема. Метки вон тоже захардкодили, и никому это не мешает. И регистры, и арифметику массивов. Если у вас уже есть указатели на все случаи жизни и вы не полагаетесь на разум программиста (как делают Си-шники) так зачем выставлять опасный низкоуровневый инструмент наружу, да еще и ругаться на его использование.
На счет "разума программиста" не трактуйте неправильно. В Си совершенно законно неявное приведение типов вроде int *arr=malloc(10), язык предполагает что программист может делать все, что компилятор способен распознать. Хочет использовать хаки, основанные на UB - его право. Более высокоуровневые языки обычно бьют за такое по рукам.
Цитата Сообщение от Renji Посмотреть сообщение
Собственно, и VLA пытаются утащить по соображениям удобства плюсовиков. Но пока не утащили, его поддержка - блажь конкретного компилятора.
Так vla и в Си долгое время было просто очередным gnu-тым расширением. Да и сейчас остается: до конца в стандарт его не ввели.
Цитата Сообщение от Renji Посмотреть сообщение
Ради массива с 8-битовыми масками.
Чем это лучше просто восьмибитных масок uint8_t, заполняемых макросом? Ведь ваш код делает тоже самое, только длиннее и запутаннее.
Цитата Сообщение от Renji Посмотреть сообщение
А вот как вы тоже самое провернете на макросах я слабо себе представляю. Разве что ручками будете объявлять четыре практически идентичных массива.
В смысле? Я же привел код: задается буква порта, задаются номера битов.
Цитата Сообщение от Renji Посмотреть сообщение
Вас кто-то дизинформировал. RAMPX, RAMPY, RAMPZ нужны только чтобы вылезти за пределы текущего 64-килобайтового сегмента. Для 16-битовых адресов которые использует ваш код, можно использовать любой регистр. Вот, смотрим в доку и видим там ld r2,X.
Ох лол, еще он мне рассказывать будет про ограничения команд AVR. Человек, не знающий о контроллерах ровно ничего будет учить человека более чем с 10-летним опытом. Причем начинал я именно с ассемблера.
RAMPX, RAMPY, RAMPZ это вообще не РОН, это регистры ввода-вывода, в них даже нельзя писать напрямую.
Что ж, вперед, продемонстрируйте как будете пихать адрес куда-то кроме регистровых пар X, Y, Z. Что-то вроде ld r2, r16.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,416
18.08.2019, 09:36
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В Си совершенно законно неявное приведение типов вроде int *arr=malloc(10), язык предполагает что программист может делать все, что компилятор способен распознать.
Это неявное приведение void * -> int *, которое в Си действительно "совершенно законно". Неявные приведения иных несвязанных указательных типов в Си совершенно НЕзаконны. Не ясно, о каком "компилятор способен распознать" вы ведете речь.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
18.08.2019, 10:04
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В именах своих переменных, называемых var1, var2, в индексах цикла i->j - это сколько угодно. Но вот чтобы printf перепутать с sprintf - такого не видел.
Вероятно, потому что s и p на клавиатуре далеко, а 1 и 2 рядом. Еще раз, в пример ошибки приводился scanf->sscanf. Это даже не "палец не в ту кнопку попал", а "два раза по одной стукнул".
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ничего подобного. Структуры в С++ это лишняя сущность, которая должна бы реализовываться через класс, но ради совместимости с Си решили протащить в неизменном виде. А чтобы не было нужды писать class{public: достаточно было сделать поля по дефолту публичными.
Ради совместимости с Си достаточно было поддерживать лишь корректный экспорт функций и совместимость ABI. Что собственно и делает множество языков позволяющих подключить сишные либы, но ни о какой совместимости синтаксиса знать не знающие.
По классам да, надо было уже признать идею private по умолчанию неудачной и сделать наоборот. Но пока не признали, выкручиваемся с struct.
По умным указателям - если их захардкорить, потеряется возможность кастомные аллокаторы прикрутить.

И нет, хаки основанные на UB незаконны ни в Си, ни в плюсах. Вы путаете UB с implementation defined.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В смысле? Я же привел код: задается буква порта, задаются номера битов.
В смысле, решаем вами же предложенную задачу "индикатор может висеть на разных портах". Что лично я понял как "одна нога на одном порте, другая на другом". Ваш seg_codes подходит только для случая когда индикатор висит на одном порте. При попытке расширить это на несколько портов, придется для каждого пилить свой seg_codes.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что ж, вперед, продемонстрируйте как будете пихать адрес куда-то кроме регистровых пар X, Y, Z. Что-то вроде ld r2, r16.
Ну, так как под рукой у меня только документация, а не сам микроконтроллер... Окей, окей, признаем что разрешены только три регистра и добавляем mov константы из произвольного регистра в положенный. Суть не меняется - две команды для загрузки константы явно лишние.
0
 Аватар для COKPOWEHEU
4150 / 2728 / 433
Регистрация: 09.09.2017
Сообщений: 12,099
18.08.2019, 17:41
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Неявные приведения иных несвязанных указательных типов в Си совершенно НЕзаконны. Не ясно, о каком "компилятор способен распознать" вы ведете речь.
Особенно в С89 (или какая там первая версия), где void* не было вообще.
под "способен распознать" я имею в виду "способен скомпилировать", не важно с каким количеством UB и прочего.
Цитата Сообщение от Renji Посмотреть сообщение
Это даже не "палец не в ту кнопку попал", а "два раза по одной стукнул".
Это в глаза бросается! В отличие от счетчиков, где i и j похожи визуально и применяются минимум в 3 местах, scanf и sscanf нельзя перепутать ни внешне, ни по использованию. Ну по крайней мере вероятность такой ошибки не выше, чем любой другой. И снижать читаемость кода всякими std::string_scan_format явно не стоит.
Цитата Сообщение от Renji Посмотреть сообщение
Ради совместимости с Си достаточно было поддерживать лишь корректный экспорт функций и совместимость ABI.
И еще раз предлагаю начинать вводить новые ветки спора с обоснования каким же они боком к изначальной теме. Совместимость нескольких языков по ABI никакого отношение к "совместимости с исходным кодом Си" не имеет.
Цитата Сообщение от Renji Посмотреть сообщение
Но пока не признали, выкручиваемся с struct.
"выкручивались" бы если бы struct ввели позже class как частный случай под конкретную задачу. Но ведь в реальности все наоборот - поверх struct прикручивали ООП. И тянут до сих пор, потому что struct постоянно используется в Си-шном коде, который плюсовики хотят компилировать.
Цитата Сообщение от Renji Посмотреть сообщение
И нет, хаки основанные на UB незаконны ни в Си, ни в плюсах. Вы путаете UB с implementation defined.
Интерпретация памяти float как целого числа это UB или ID? Как бы незаконно, но полезно
Переполнение целых - UB или ID? Как бы незаконно, но полезно
Разыменование нулевого указателя?
Цитата Сообщение от Renji Посмотреть сообщение
В смысле, решаем вами же предложенную задачу "индикатор может висеть на разных портах".
То есть вы не заметили, что исходная задача была про один порт, и даже было объяснено почему это имеет смысл? Что ж тогда не выбрали самую усложненную версию, где многоразрядный индикатор? То, что вы не решили "среднюю" задачу - не удивляет, почему я и предложил начать с простейшей.
Цитата Сообщение от Renji Посмотреть сообщение
Ваш seg_codes подходит только для случая когда индикатор висит на одном порте.
Тут производительность явно будет ниже (о чем я уже писал), но например можно так:
C
1
2
3
4
5
6
7
8
9
10
void led7_show( uint8_t num ){
  uint8_t code = seg_nums[ num ];
  PORT_OFF( SEG_A ); if( code & (1<<0) )PORT_ON( SEG_A );
  PORT_OFF( SEG_B ); if( code & (1<<1) )PORT_ON( SEG_B );
  PORT_OFF( SEG_C ); if( code & (1<<2) )PORT_ON( SEG_C );
  PORT_OFF( SEG_D ); if( code & (1<<3) )PORT_ON( SEG_D );
  PORT_OFF( SEG_E ); if( code & (1<<4) )PORT_ON( SEG_E );
  PORT_OFF( SEG_F ); if( code & (1<<5) )PORT_ON( SEG_F );
  PORT_OFF( SEG_G ); if( code & (1<<6) )PORT_ON( SEG_G );
}
по 3 такта на каждый сегмент.
Цитата Сообщение от Renji Посмотреть сообщение
добавляем mov константы из произвольного регистра в положенный. Суть не меняется - две команды для загрузки константы явно лишние.
Через регистр передали индекс элемента в массиве. Адрес начала откуда возьмете?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,416
18.08.2019, 18:16
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Особенно в С89 (или какая там первая версия), где void* не было вообще.
void * присутствует в С с самого первого стандарта. "void* не было вообще" - это эпоха туманных эскизов языка.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
под "способен распознать" я имею в виду "способен скомпилировать", не важно с каким количеством UB и прочего.
Что такое "способен скомпилировать" в применении к языку? Язык ничего никогда не "компилирует".

В языке С попытка неявное приведения несвязанных типов указателей - это constraint violation, сразу грубая ошибка. Никакого "способен распознать" или "способен скомпилировать" тут нет и быть не может. Как уже было не раз сказано, ни в С, ни в С++, не допускается неявное приведение таких указателей.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.08.2019, 18:16

std::vector<int> Что это за тип данных?
std::vector&lt;int&gt; indexes_1, indexes_2; // Used for homography Что это за тип данных?

Что значит (для сущности «вершина» создать новый тип данных)?
Задание такое: Написать функцию для вычисления площади треугольника на плоскости, заданного координатами вершин. (для сущности «вершина»...

Восьмибитный тип переменной (что за тип, но не BYTE и не CHAR?
Вроде давно занимаюсь программированием на С++, но встала проблема... Есть некий массив переменных имеющих 8 битный размер... без знака...

Объясните, что это: "static const uint32_t collisionCategory = 0x1 << 0"?
Встретил в одном туториале по SpriteKit следующую строчку static const uint32_t projectileCategory = 0x1 &lt;&lt; 0; Подскажите...

Как сделать тип данных или уже есть такой тип данных который состоит из всех печатыемых символов?
Как сделать тип данных или уже есть такой тип данных который состоит из всех печатыемых символов? Если есть то как он называется ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
140
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru