Перейти к содержанию
    

Плавный переход C -> C++ под МК

В 13.03.2024 в 14:30, EdgeAligned сказал:

Ааа, понял, вы просто не знаете, что такое строгая типизация.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, виноват, действительно 😄 я тут про строгую типизацию, про сложные материи а у вас тут спор всего лишь про то, большими или маленькими буковками написать 😄 ну да, канешн, тут просто разные уровни темы, хе-хе. Лано, извините, больше не вмешиваюсь в ваш спор про большие и маленькие буковки, продолжайте, коллеги!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 12.03.2024 в 01:44, Arlleex сказал:
enum eMyEnum { e10 = 10, eMY_ENUM_VAL } // enum (если надо отличать от #define, то по префиксу'e' в значениях, если не надо - не пишем)

вот от куда ноги спора диалога растут. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пишу шаблон структуры и задаю все необходимые мне специализации

enum Command {
  SPI_SEND_FLASH,
  SPI_SEND_RAM,
  SPI_SEND,
  SPI_FILL,
  SET_PIN,
  RESET_PIN,
  WAIT,
  CALL
};

template<Command>
struct Descriptor;

template<>
struct Descriptor<SPI_SEND_FLASH> {
  Command cmd  :  3;
  bool    dc   :  1;
  u32     addr : 19,
          size :  9;
};

...

template<>
struct Descriptor<CALL> {
  Command cmd : 3;
  u16     arg;
};


Теперь самое важное: создаваемые структуры должны быть упакованы, чтобы компилятор не вольничал. Для экономии памяти мне обязательно нужно, чтобы все структуры занимали одно 32-битное слово.

Если я укажу атрибуты в объявлении

template<Command>
struct __attribute__((packed)) Descriptor;

, то "распространится" ли этот атрибут на определения специализаций?

Или мне в каждой специализации теперь писать этот атрибут?

P.S. Отвечаю себе сам. Нет, не распространяется и, судя по всему, просто игнорируется молча. Каждой специализации нужно задавать атрибуты отдельно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Советую по теме С++ в МК посмотреть на http://mypractic.ru/uroki-stm32 , и в частности, на http://mypractic.ru/urok-13-razrabotka-i-ispolzovanie-klassov-v-c-sozdanie-klassa-obrabotki-diskretnyx-signalov-debounce.html, Там статья "Урок 13. Разработка и использование классов в C++. Создание класса обработки дискретных сигналов Debounce.". Но это все - простые примеры 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему при введении шаблона функции нужно обязательно присутствие всех параметров шаблона в качестве формальных параметров функции?

Т.е. допустимо

template<class A, class B>
void func(A a, B b) {
  ...
}

и недопустимо

template<class A, class B>
void func(A a) {
  B b;
  ...
}

несмотря на то, что тип B используется в теле функции.

Учебники пишут только декларативно, зачастую (как в моем случае) не объясняя причин.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Потому что компилятор не сможет установить правильный тип для этих параметров при вызове функции.

 

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

Вы потом сделаете вызов 

int asd;

func(asd);

 

компилатор сгенерирует func(int). А какой тип будет В?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 минуту назад, Arlleex сказал:

и недопустимо

допустимо, при явном указании типа. например

template<class A, class B>
void func(A a) {
  B b;
  ...
}

void main()
{
  func<MyClass, YourClass>(2);//так норм
  func(2); //ошибка
  
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, juvf сказал:

Потому что компилятор не сможет установить правильный тип для этих параметров при вызове функции.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно ли в C++ как-то красиво описать структуру с гибким положением последнего элемента?

Допустим, есть структура

struct TxRS485 {
  Header hdr;
  u8     byte[N];
  u32    crc;
}


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

Задача простая (и применяемая ну совсем повсюду): из поля ввода юзер-данных считать строчку, запихнуть ее в структуру с определенным паттерном (снабдив заголовками и т.д.), последним элементом должен "приклеиться" CRC-чек.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, Arlleex said:

Можно ли в C++ как-то красиво описать структуру с гибким положением последнсего элемента?

с "гибким"? чтобы менялось в рантайме? так конечно нет, это ж структура ))

но можно хранить в структуре указатель на массив с данными

Или остается использовать кучу, а это известно что за собой несет. Если идти с кучей дальше, то есть в конце концов std::vector

 

можно немного изменить протокол введя ограничение по длине поля данных и добавить поле длины данных (один или два байта)

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

еще придется переместить поле контрольной суммы ДО начала данных, никто не заставляет хранить ее в самом конце

так делал, работало прекрасно, да и щас работает )

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я от того и спрашиваю, что задача тривиальная, а решалась всегда "криво"🙂

Но, видимо, нужно создать класс-оболочку над неким массивом известной длины (достаточной, чтобы вместить нужное количество данных) и с ним уже работать.

8 минут назад, Forger сказал:

можно немного изменить протокол введя ограничение по длине поля данных и добавить поле длины данных (один или два байта)

Длину не нужно передавать, т.к. сам протокол умеет детектировать ее по механизму кадрирования нижних уровней.
 

Цитата

еще придется переместить поле контрольной суммы ДО начала данных, никто не заставляет хранить ее в самом конце

ИМХО, ужасное решение🙂 Потому что у меня десятки разных управляющих структур бегают, с разным содержимым и длиной. Контрольную сумму логично располагать где-то в одном конкретном месте для всех структур: и это либо начало кадра, либо самый его хвост. Иначе, чтобы определить положение КС, нам надо "узнать", что это за структура, а лезть в ее поля, не проверив КС - нельзя. У меня "узаконен" формат с CRC в хвосте. Алгоритм приема и отбраковки битых кадров становится универсальным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, Arlleex said:

ИМХО, ужасное решение

Хорошо что ИМХО. У меня примерно как Forger написал. Работает всё прекрасно. Данные по указателю. И с динамическими и со статическими данными.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 15.04.2024 в 11:58, Forger сказал:

есть в конце концов std::vector

плюсую

#include <vector>

struct TxRS485
{
	Header hdr; 
	std::vector<u8> bytes;
	u32 crc; 
};

Использование

TxRS485 tx; 

tx.bytes.push_back(0x01); // добавление элемента в вектор 
tx.bytes.push_back(0x02); 

// Размер вектора может быть изменен динамически 
tx.bytes.resize(10); 

// Получение доступа к элементам вектора 
tx.bytes[0] = 0x11; 
tx.bytes[1] = 0x22;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...