Easyelectronics.ru

Электроника для всех
Текущее время: 23 янв 2021, 01:21

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 07:15 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Здраствуйте.

Может кто в курсе как, что нужно сделать/настроить для arm-none-eabi, что бы списки инициализации корректно работали в конструкторе?
Вот пример:
Код:
/* Public Constructors */
TestClass::TestClass(void): _bitLock(0), _listCh{0} {
}


По правильному этот конструктор ничего с моими переменными не должен делать так как я данные переменные инициализирую уже известными значениями. Другими словами должно быть как в Си в таком случае:
Код:
size_t        test;


В переменной будет ноль, C++ не понимает этого и конструктор TestClass впихивает для зануления memset - что является лишним действием.
Может кто знает как можно его научить адекватно реагировать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 07:53 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
чудес НЕ бывает.
гдето, на каком то этапе, обязан выполнится некоторый код который подготовит обнулит/очистит область памяти.

в одних случаях это происходит явно - в других скрыто. тчк.

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 12:39 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
Код:
size_t        test;

В переменной будет ноль, C++ не понимает этого и конструктор TestClass впихивает для зануления memset - что является лишним действием.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:17 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
cheblin писал(а):
чудес НЕ бывает.
гдето, на каком то этапе, обязан выполнится некоторый код который подготовит обнулит/очистит область памяти.

в одних случаях это происходит явно - в других скрыто. тчк.


Так это есть - и оно сделано и вся память обнуляется и константные значения переносятся. И си про это знает. А вот с++ нет. И вопрос как ему сообщить для начало хотя бы об том, что память как и положена занулена и что бы он повторно не занулял ее.


Последний раз редактировалось hapr-lera 14 ноя 2020, 14:25, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:18 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Reflector писал(а):
hapr-lera писал(а):
Код:
size_t        test;

В переменной будет ноль, C++ не понимает этого и конструктор TestClass впихивает для зануления memset - что является лишним действием.

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


Специальный код это делает про который с++ не в курсе...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:25 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
Специальный код это делает про который с++ не в курсе...

Или не делает:
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:27 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Reflector писал(а):
hapr-lera писал(а):
Специальный код это делает про который с++ не в курсе...

Или не делает:
Изображение

В моем случае сделано через init, а тут значит нужно добавить...
Тем более тут локальная переменная - она вообще не должна быть занулена.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:34 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
Цитата:
И си про это знает.


malloc() allocates memory block of given size (in bytes) and returns a pointer to the beginning of the block. malloc() doesn’t initialize the allocated memory.

calloc() allocates the memory and also initializes the allocated memory block to zero.


вот и вся магия

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:38 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
cheblin писал(а):
Цитата:
И си про это знает.



malloc() allocates memory block of given size (in bytes) and returns a pointer to the beginning of the block. malloc() doesn’t initialize the allocated memory.

calloc() allocates the memory and also initializes the allocated memory block to zero.

Ну да за фасадом.
Но можно все таки как то с++ объяснить, что не бойся и списки используй все хорошо у нас хоть это arm, но мы сами память себе обрабатываем и можешь действовать как и на pc, так что будь добр не делай лишнего?

Хотя я что то не понял. А calloc причем? - его нет только статичная память поддерживается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:48 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
В моем случае сделано через init, а тут значит нужно добавить...

Сделать то что хочется? Если явно вызывается init(), то зачем ты сам в конструкторе обнуляешь поля?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:55 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
если так уверен, и знаешь как внутри всё работает
так выдели нужный кусок памяти и приведи её к любому требуему типу. этож С++

_________________
unirail.org


Последний раз редактировалось cheblin 14 ноя 2020, 14:56, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:56 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Reflector писал(а):
hapr-lera писал(а):
В моем случае сделано через init, а тут значит нужно добавить...

Сделать то что хочется? Если явно вызывается init(), то зачем ты сам в конструкторе обнуляешь поля?


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:57 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
с чем боремся, не понимаю? или точнее за что? с производительностью проблема?

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 14:58 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
cheblin писал(а):
если так уверен, и знаешь как внутри всё работает
так выдели нужный кусок памяти и приведи её к любому требуему типу. этож С++


Можно и так само собой, так же можно и не занулять явно. Но как то это не очень...
Я надеялся, что в gcc arm есть какой флаг, что бы указать c++, что все ок и занулять не нужно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 15:00 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
с чем боремся? чего нехватает в жизни?

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 15:02 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
cheblin писал(а):
с чем боремся, не понимаю? или точнее за что? с производительностью проблема?

Я просто хочу, что бы с++ ожидаемо работал))
Другими словами не нужно было бы так делать:

Код:
TestClass::TestClass(void){// _bitLock(0), _listCh{0}  тупой с++ не знает, что память занулена поэтому, явно не указываем, что нужно в переменных нули. Но имеем в виду, если так вдруг перестанет быть то все у вас полетит из-за этого кода
}


Не люблю лишний код как и не определённости в коде...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 15:04 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
всё. расходимся. тут не на что смотреть

Изображение

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 15:33 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
Я надеялся, что в gcc arm есть какой флаг, что бы указать c++, что все ок и занулять не нужно.

Похожая фишка есть в D, там все переменные, даже локальные, инитятся нулем, но это можно запретить:
Код:
int x = void;

Работает с массивами и структурами, не работает с классами, видимо не просто так... Для C++ видел только похожие предложения, может в будущем что-то подобное и появится.

Цитата:
тупой с++ не знает, что память занулена поэтому, явно не указываем, что нужно в переменных нули. Но имеем в виду, если так вдруг перестанет быть то все у вас полетит из-за этого кода

В защиту C++ могу сказать, что тупых программистов тоже предостаточно :) Возьмем простой код с глобальным экземпляром класса:
Код:
class Test
{
public:
   Test() : x(0), y(0) {}
   int x, y;
};

Test test;
GPIOB->ODR = test.y;

У него непустой конструктор и он будет где-то в стартапе вызываться, но можно сделать так:
Код:
class Test
{
public:
   Test() = default;
   int x = 0, y = 0;
};


Test test;
GPIOB->ODR = test.y;

И размер бинарника удивительным образом уменьшился на 8 байт :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 15:48 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Цитата:
И размер бинарника удивительным образом уменьшился на 8 байт :)


Неа не прокатывает, он при Test() = default; - просто все переменные не инициализированные 0 или же им инициированные 0 - через memset нулем забивает. То есть тоже самое как и при списке.
Другими словами конструктор все равно вызывается, только не мой а свой создаеться.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 16:04 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 3807
Откуда: Китай, Пекин
Цитата:
так выдели нужный кусок памяти и приведи её к любому требуему типу.

универсальней небывает

_________________
unirail.org


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 16:10 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
cheblin писал(а):
Цитата:
так выдели нужный кусок памяти и приведи её к любому требуему типу.

универсальней небывает

Если я буду кусок памяти в ручную выделять в классе под переменные простые, то универсальностью и не пахнет как по мне. Плюс проблема у меня ведь не в типах а в том, что бы с++ распознавал, что не в динамически создаваемых классах не нужно переменные занулять в ручную.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 17:19 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
Неа не прокатывает, он при Test() = default; - просто все переменные не инициализированные 0 или же им инициированные 0 - через memset нулем забивает. То есть тоже самое как и при списке.

Обнулять переменные компилятору все равно придется, если вызывается memset, то видимо переменных много и так получается эффективнее. В любом случае я бы не парился из-за такой ерунды, а у меня пунктик на оптимизациях :) Например, есть у меня либа для работы с разными дисплеями подключаемыми через FMC/SPI/GPIO, во всех случая конструкторы пустые и RAM не потребляется совсем. Это типично для периферии в целом, если же мне нужен класс чтобы браузить файлы на SD, то он будет использовать класс дисплея, но дополнительно добавится довольно много переменных, однако получившийся класс будет слишком высокоуровненым чтобы переживать из-за лишней инициализации полей...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 17:48 
Только пришел

Зарегистрирован: 14 ноя 2020, 07:03
Сообщения: 18
Цитата:
Обнулять переменные компилятору все равно придется, если вызывается memset, то видимо переменных много и так получается эффективнее

Да не придеться! Я ведь писал, что в коде организовано обнуление памяти.

Другими словами если на Си сделать так:
Код:
int array[200] = {0};

То memset не будет использоваться, так как Си знает, что раз есть секция bss то туда можно пихать такие переменные и самому уже не нужно занулять. А вот с++ с этим тупит.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 18:26 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2900
Откуда: Санкт-Петербург
А что, C++ должен вам сгенерить два отдельных конструктора, один для статических переменных (без зануления), другой для тех, что лежат в стеке или куче (с занулением)? И так для всей иерархии наследования (если она есть)?

Напомню: конструктор – это просто функция.

ЗЫ: И стоит ли шибко биться только ради того, чтобы оптимизировать инициализацию статических переменных? Она выполнится ровно один раз.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: c++ списки инициализации
СообщениеДобавлено: 14 ноя 2020, 18:42 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1396
hapr-lera писал(а):
Другими словами если на Си сделать так:
Код:
int array[200] = {0};

То memset не будет использоваться, так как Си знает, что раз есть секция bss то туда можно пихать такие переменные и самому уже не нужно занулять. А вот с++ с этим тупит.

Я же приводил пример... Давай еще раз, на этот раз с массивами:
Код:
int arr[100] = { 0 };

for (int i = 0; i < 100; i++)
{   
   GPIOA->ODR = arr[i] | GPIOB->ODR;
}

И массив внутри класса:
Код:
class Test
{
public:
   Test() = default;
   int arr[100] { 0 };
};

Test test;

for (int i = 0; i < 100; i++)
{   
   GPIOA->ODR = test.arr[i] | GPIOB->ODR;
}

Для этих двух примеров бинарники абсолютно идентичные!


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB