Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Сб ноя 24, 2012 14:02:39

Сообщение matrex »

A!!! Все ясно. Нет ничего лучше, как своевременный пример по делу. Все сразу стало на свои места. С правильным подходом удалось сэкономить еще и сотню байт. Спасибо.
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Тут не просто переменные, а объект неизвестного размера. Где же его ещё создавать, не в стеке или куче же. Да ещё чтобы доступен из других единиц трансляции был.
Так я несколько не об этом. Я имел в виду, что эту переменную нужно запирать в модуле, чтобы её не было видно глобально во всей программе.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="da-nie",url="/forum/viewtopic.php?p=3832796#p3832796"]Так я несколько не об этом. Я имел в виду, что эту переменную нужно запирать в модуле, чтобы её не было видно глобально во всей программе.[/uquote]Зачем? Это глобальный ОБЪЕКТ - экран. Работа с ним осуществляется через его методы. Что там ещё прятать? Всё и так внутри объекта. То что автор решил его тягать как обычную переменную по функциям... Ну это он ССЗБ.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

То что автор решил его тягать как обычную переменную по функциям... Ну это он ССЗБ.
Вот это и прятать.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

А кстати, в плюсах если объект передавать как указатель в аргументах функции, накладных расходов же будет?

Добавлено after 1 minute 53 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=3832683#p3832683"]В arduino ide компилятор gcc, который С++ только в путь. Сам по себе C++ не даёт накладных расходов, если с головой подходить, а не так как matrex.[/uquote]
Не просто в путь. Весь Arduino Core (те самые библиотеки, на которых все строится в ардуино) основан на плюсах с ооп. Тот же Serial - объект. И многие другие вещи классами описаны.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="NStorm",url="/forum/viewtopic.php?p=3832871#p3832871"]А кстати, в плюсах если объект передавать как указатель в аргументах функции, накладных расходов же будет?[/uquote]В этом случае передаётся не "объект как указатель", а указатель. Накладные будут при доступе по этому указателю. Насколько большие зависит от архитектуры. При развитых типах адресации может и не быть накладных.
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.

Сообщение da-nie »

Накладные будут при доступе по этому указателю.
Не должно быть. Когда вызывается функция класса, ей так или иначе передаётся указатель на класс. Исключение - статические функции.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Сб ноя 24, 2012 14:02:39

Сообщение matrex »

Ну раз пошел у нас такой задушевный диалог, разрешите еще вопрос. Как правильно инициализировать структуру (по сути массив) нулями. В идеале одной командой сразу всю.

Код: Выделить всё

// данные с датчиков
struct rSENSORS
{
    float aPRESSURE[SENSOR_COUNT_DATA]; // Давление
    float aTMP_IN[SENSOR_COUNT_DATA];   // Температура внутри помещения
    float aTMP_OUT[SENSOR_COUNT_DATA];  // Температура на улице
    uint8_t aHOUR[SENSOR_COUNT_DATA];   // Час снятия показания
    uint8_t aMINUTE[SENSOR_COUNT_DATA]; // Минута снятия показания
};
Делаю "в лоб" (работает, но не изящно, знаю что можно лучше):

Код: Выделить всё

    rSENSORS dt;

    for (uint8_t cnt = 0; cnt < (SENSOR_COUNT_DATA - 1); cnt++)
    {
        dt.aPRESSURE[cnt] = 0;
        dt.aTMP_IN[cnt] = 0;
        dt.aTMP_OUT[cnt] = 0;
        dt.aHOUR[cnt] = 0;
        dt.aMINUTE[cnt] = 0;
    }

Пытаюсь через memset (в начале вроде как работало, но потом из-за того что похоже подход не верный, начали разрушаться переменные):

Код: Выделить всё

memset(dt.aPRESSURE, 0, sizeof dt.aPRESSURE);	
memset(dt.aTMP_IN, 0, sizeof dt.aTMP_IN);	
memset(dt.aTMP_OUT, 0, sizeof dt.aTMP_OUT);	
memset(dt.aHOUR, 0, sizeof dt.aHOUR);	
memset(dt.aMINUTE, 0, sizeof dt.aMINUTE);	
В итоге - никак не инициализирую массив (все работает, экономит десяток байт) - вроде как из спецификации CPP там должны находиться нули по умолчанию, но меня терзают сомнения, а предыдущий опыт говорит о том, что переменные лучше инициализировать явно во избежании лишних проблем.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

matrex писал(а):Делаю "в лоб"
а вот так не в лоб?

Код: Выделить всё

typedef struct
{
    float aPRESSURE[SENSOR_COUNT_DATA]; // Давление
    float aTMP_IN[SENSOR_COUNT_DATA];   // Температура внутри помещения
    float aTMP_OUT[SENSOR_COUNT_DATA];  // Температура на улице
    uint8_t aHOUR[SENSOR_COUNT_DATA];   // Час снятия показания
    uint8_t aMINUTE[SENSOR_COUNT_DATA]; // Минута снятия показания
}  rSENSORS;

rSENSORS dt;

	memset(&dt, 0, sizeof(rSENSORS));
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="matrex",url="/forum/viewtopic.php?p=3832994#p3832994"]Вроде как из спецификации CPP там должны находиться нули по умолчанию[/uquote]Это верно для глобальных переменных. Всё остальное будь добр инициализировать.

Добавлено after 2 minutes 45 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3833003#p3833003"]

Код: Выделить всё

memset(&dt, 0, sizeof(rSENSORS));
[/uquote]На ARM нужно 10 раз подумать прежде чем так делать, чтобы исключить невыровненный доступ там где его нет и в HardFault не улететь. Можно, но с головой!
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

А зачем вы создали структуру из массивов? У вас же размерность одинаковая. Сделайте массив структур.

Код: Выделить всё

struct rSENSORS
{
    float aPRESSURE; // Давление
    float aTMP_IN;   // Температура внутри помещения
    float aTMP_OUT;  // Температура на улице
    uint8_t aHOUR;   // Час снятия показания
    uint8_t aMINUTE; // Минута снятия показания
} dt[SENSOR_COUNT_DATA];
Если уже отличное от нулей, то тогда можно делать так:

Код: Выделить всё

...
} dt[SENSOR_COUNT_DATA] = { [1].aPRESSURE = 123, [2].aHOUR = 12 };
Можно в т.ч. написать = { 0 }.

Или сделать уже memset(dt, 0, sizeof dt);. Одна инструкция, а не для каждого члена структуры, как у вас.

Песочница: https://godbolt.org/z/2JgWai

Если настаиваете на вашей структуре с массивами, то тогда можно и так обнулять:

Код: Выделить всё

dt = (struct rSENSORS){ 0 };
Последний раз редактировалось NStorm Пн апр 27, 2020 12:48:09, всего редактировалось 1 раз.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

VladislavS писал(а):На ARM нужно 10 раз подумать прежде чем так делать, чтобы исключить невыровненный доступ там где его нет и в HardFault не улететь.
было бы конструктивно объяснить, как следует поступать, чтобы не нарваться. причем без привзяки к ARM, а вообще по правильному для С++, раз уж тема об этом языке.
NStorm писал(а):Или сделать уже memset(dt, 0, sizeof dt);
это чем-то отличается от предложенного мной?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3833032#p3833032"]На ARM нужно 10 раз подумать прежде чем так делать, чтобы исключить невыровненный доступ там где его нет и в HardFault не улететь. Можно, но с головой![/uquote]
++
Еще memcpy опасен. Я пару раз нарывался. Вроде код правильный, а в хардфолт уходит. Оказывается, пытался при помощи memcpy копировать часть строки (а memcpy, видимо, оптимизировать пытался и копировать по 4 байта "за присест"). В общем, если строки нужно копировать, то есть strcpy — она не пытается char'ы как uint32_t копировать…
И в packed-структурах приходится очень аккуратно члены располагать.
[uquote="ARV",url="/forum/viewtopic.php?p=3833063#p3833063"]было бы конструктивно объяснить, как следует поступать, чтобы не нарваться. причем без привзяки к ARM[/uquote]
А смысл тогда о выравнивании думать?
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 28
Зарегистрирован: Сб ноя 24, 2012 14:02:39

Сообщение matrex »

Спасибо коллеги из помощь и советы по существу.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Eddy_Em писал(а):А смысл тогда о выравнивании думать?
смысл в понимании ограничений С++. я, например, крайне удивлен тем фактом, что функция, копирующая заданное (любое!) количество БАЙТ может куда-то уходить в хардфаулт - она не имеет права оптимизировать что-то так, как нельзя! если это где-то оговорено в стандарте С++, то об этом и стоит говорить на публичном форуме, а не о своей печальной судьбе...

что касаетс ARM, то С++ существует для бОльшего количества платформ, и для разрядностей тоже, чем единственное семейство ARM. поэтому и говорить надо об особенностях С++ для РАЗНЫХ платформ.

я вот еще был очень сильно удивлен, что union в С++ это совсем не тот же union, что в Си. но так и не понял, из-за чего эта разница НЕ ВСЕГДА бывает. тоже хотел бы узнать от сведущих людей...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

[uquote="ARV",url="/forum/viewtopic.php?p=3833063#p3833063"]это чем-то отличается от предложенного мной?[/uquote]
Неа. Я до падения форума еще ответ написал, до того как ваш увидел.
Хотя посыл у меня был больше в том, что в таких случаях обычно делают массив структур, а не как ТЫ структуру из массивов (одинаковой размерности).

Добавлено after 5 minutes 46 seconds:
Без мемсета легко как я уже написал инициализировать нулевой локальной переменной, вроде dt = (struct rSENSORS){ 0 };.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="ARV",url="/forum/viewtopic.php?p=3833080#p3833080"]смысл в понимании ограничений С++. я, например, крайне удивлен тем фактом, что функция, копирующая заданное (любое!) количество БАЙТ может куда-то уходить в хардфаулт - она не имеет права оптимизировать что-то так, как нельзя![/uquote]
Вообще-то, stdlib — он на то и stdlib, что там все более-менее оптимизировано, чтобы не приходилось каждому делать свой велосипед-квадратные-колеса для элементарных strcpy и т.п. А вот на микроконтроллеры, к сожалению, это не распространяется, т.к. оптимизация stdlib и других библиотек знать не знает, что есть какая-то говножелезка, разработчики которой были настолько долбанутыми ослами, что сделали обязательным требованием выравнивание переменных в памяти!

Это вам вопрос задавать надо не к разработчикам стандарта С++, а к ослам, которые заложили в архитектуру ARM такой огромный косяк!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ARV",url="/forum/viewtopic.php?p=3833080#p3833080"]смысл в понимании ограничений С++.[/uquote]Причём тут С++? Это вообще стандартные C-ные функции. Проблема не в языке, а в разработчике конкретной библиотеки и конкретного компилятора. Я же не просто так ему передаю параметр "-mcpu=cortex-m0" или "-mcpu=cortex-m4". Он должен это учитывать при компиляции/оптимизации. Это не ограничение языка!

Добавлено after 6 minutes:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3833090#p3833090"]Вообще-то, stdlib — он на то и stdlib, что там все более-менее оптимизировано, чтобы не приходилось каждому делать свой велосипед-квадратные-колеса для элементарных strcpy и т.п. А вот на микроконтроллеры, к сожалению, это не распространяется, т.к. оптимизация stdlib и других библиотек знать не знает, что есть какая-то говножелезка, разработчики которой были настолько долбанутыми ослами, что сделали обязательным требованием выравнивание переменных в памяти![/uquote]Это не так. stdlib должна правильно работать на любой железке. Библиотека оптимизируется под конкретную железку. То что в определённых условиях она сбоит - это недоработка, которую разработчик обязан исправлять, особенно если продукт платный.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

у меня вопрос на счет union в C++

Код: Выделить всё

typedef union{
   struct{
      uint8_t a;
      uint8_t b;
   };
   uint8_t c;
} my_type;
почему sizeof(my_type) == 3?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Не верь глазам своим
Изображение
Вложения
my_type.png
(32.93 КБ) 456 скачиваний
Ответить

Вернуться в «Разные вопросы по МК»