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

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

3 часа назад, esaulenka сказал:

Вот объяснение, почему так нельзя делать в C++: https://isocpp.org/wiki/faq/ctors#ctor-initializer-order

Читать всё лень, но вроде там речь только про инициализацию пользовательских типов данных? А не встроенных.

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


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

Под вечер что-то не вдупляю. Что здесь не так?

static struct {
  bool isValid;

  struct {
    struct {
      u8 const addr;
      u8       val;
    } reg[] = {
      {0x50, 0},
      {0x51, 0},
      {0x52, 0},
      {0x53, 0},
      {0x54, 0}
    };
  } mux[4];
} RegCache;
sources/drivers/dvi_mux.cpp(14): error: array bound cannot be deduced from a default member initializer


Если явно указать размер reg[5], то все ок.

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


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

Об этом же и написано. Укажите размер. Размер класса нужно знать  на этапе компиляции. Массив - это не указатель, вопреки распространённому мнению.

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


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

Да, я уже понял. Сбила с толку строка о якобы "границе массива".

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

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


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

Какой-то бред творится, объяснений найти не могу.

Имеем вот такую конструкцию

struct sRegCache {
  struct sMux {
    struct sReg {
      static u32 const addr;
    };
    
    sReg reg;
  };
  
  sMux mux;
};

sRegCache RegCache;

int main() {
  u32 i = sRegCache::sMux::sReg::addr;
}


Так проект не собирается, ошибка

Error: L6218E: Undefined symbol sRegCache::sMux::sReg::addr (referred from main.o).


Если же прямо в определении структуры инициализировать addr

static u32 const addr = 10;

то проект собирается. Однако при попытке взять адрес

u32 const *i = &sRegCache::sMux::sReg::addr;

редактор в онлайне не подсвечивает каких-либо ошибок, однако при компиляции

Error: L6218E: Undefined symbol sRegCache::sMux::sReg::addr (referred from main.o).


Лечится это только если убрать инициализатор из структуры и написать инициализатор отдельно

u32 const sRegCache::sMux::sReg::addr = 10;


ЧЯДНТ?

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


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

19 minutes ago, Arlleex said:

Так проект не собирается, ошибка

Все правильно он ругается. Если в классе/структуре есть хоть одно поле static, нужно явно создавать его экземпляр, логично с такой же припиской static.

Как я понял по коду, это поле должно являться как бы общим для всех экземпляров класса/структуры. Так?

 

Перефразирую немного, если не очень понятно: помимо создания экземпляров класса/структуры, это статическое поле нужно создавать отдельно. Таковы правила игры )

 

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


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

Наследие языка Си - нельзя инициализовывать переменные в заголовочнике. Оное перекочевало и в С++.

Это у вас конечный вариант структуры или в нее еще будут добавляться поля? Если поля добавляться не будут, уберите лишние вложенности, они только запутывают. И будьте аккуратнее со static полями и методами, без нужды из не применяйте, потому как в С++ это всё очень тупо работает - наследие Си, залатанное на скорую руку и оставшееся до сих пор.

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


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

Forger, да, у меня, условно, есть 4 абсолютно одинаковых микросхемы на шине I2C, и я делаю регистровый кэш на чтение, чтобы из разных мест ПО не лезть в реальное чтение шины, а лезть в кэш, который периодично обновляется. Вот я и хочу иметь лаконичный объект, внутри которого адреса регистров I2C-микросхем хранятся отдельно и не занимают ОЗУ, а значения этих самых регистров "разложены по полочкам" - т.е. каждый в своем массиве.

Сделал вот так

static struct sRegCache {
  bool isValid;

  struct sMux {
    struct sReg {
      static u8 const addr[];
             u8       val;
    } reg[arrdpth(sReg::addr)];
  } mux[4];
} RegCache;

u8 const sRegCache::sMux::sReg::addr[] = {0x50, 0x51, 0x52, 0x53, 0x54};

arrdpth() - compile-time-вычислитель кол-ва элементов массива. Удобно, потому что достаточно внести нужный адрес в список адресов и место под val образуется само собой.
 

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

Если в классе/структуре есть хоть одно поле static, нужно явно создавать его экземпляр...

Это, конечно, да, но вот почему в моем примере прекрасно компилился вариант, где инициализатор я поставил в самой структуре, а не в отдельном создании экземпляра статических данных? Т.е. так - сработало, а стоило взять адрес этого объекта, как компилер заругался. Причем характер сообщений компилятора ну вот совершенно не логичный.
 

Цитата

...нужно явно создавать его экземпляр, логично с такой же припиской static.

Нет, не логично, потому что static при определении не нужен:wink:

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


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

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

и не занимают ОЗУ

Тогда это const, а не static. Слово static подразумевает то, что для всех объектов класса (структуры) это поле будет одно и то же, то есть одинаковое у всех, и адрес у него будет один.

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


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

2 минуты назад, Variant99 сказал:

Тогда это const, а не static.

Что Вы предлагаете? Убрать static из объявления addr в sReg? Ерунда получится - расход ОЗУ под копии одних и тех же чисел.

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


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

А зачем вы их в виде массива храните то? Одно устройство - один адрес, не массив адресов, а всё вместе, типа такого:

struct I2C_Device{
	const u8 bussAddress;
	u8 regs[NUMS];
};

 

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


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

Потому что обрабатывать удобно так, это во-первых, а во-вторых, Ваш вариант противоречит моим хотелкам, т.к. 'bussAddress' будет в ОЗУ.

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


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

21 minutes ago, Arlleex said:

расход ОЗУ под копии одних и тех же чисел.

По началу особо не тратье на это силы, это как экономия на спичках, только отвлекает от реального проектирования )

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


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

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

По началу особо не тратье на это силы, это как экономия на спичках, только отвлекает от реального проектирования )

4 сотни регистров в одной микросхеме, 1600 байт ОЗУ вникуда - плохое начало проектирования:wink:

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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