Вопросы по С/С++ (СИ)
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
В arduino ide компилятор gcc, который С++ только в путь. Сам по себе C++ не даёт накладных расходов, если с головой подходить, а не так как matrex.
- Реклама
А это смотря что делать.Сам по себе C++ не даёт накладных расходов
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
С дуру и хрен сломать можно. Я же говорю - с головой. А с головой даже и экономить можно научиться.
- Сообщения: 28
- Зарегистрирован: Сб ноя 24, 2012 14:02:39
Из всего сказанного понял и сделал отдельный модуль:
Размер результирующего файла не изменился, но теперь подключая этот модуль к другим я могу обратиться к u8g и rtc. Идеологически это правильно я так понимаю? Завтра проверю в железе. Спасибо за помощь.
Код: Выделить всё
#include <Arduino.h>
#include "U8glib.h" // Подключаем библиотеку U8glib
#include "Rtc_Pcf8563.h" // Часики
#ifndef _CLASSES_
#define _CLASSES_
U8GLIB_ST7920_128X64_1X u8g(10);
Rtc_Pcf8563 rtc;
#endif- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="matrex",url="/forum/viewtopic.php?p=3832691#p3832691"]Идеологически это правильно я так понимаю?[/uquote]Нет. Читайте про ключевое слово extern, для чего оно нужно и как применяется. Ну правда, это же основы, их надо знать обязательно.
- Реклама
- Сообщения: 28
- Зарегистрирован: Сб ноя 24, 2012 14:02:39
[uquote="VladislavS",url="/forum/viewtopic.php?p=3832694#p3832694"][uquote="matrex",url="/forum/viewtopic.php?p=3832691#p3832691"]Идеологически это правильно я так понимаю?[/uquote]ключевое слово extern, для чего оно нужно и как применяется. Ну правда, это же основы, их надо знать обязательно.[/uquote]
Да не требуется там extern перестает компилироваться тогда. По ощущениям эти классы уже объявлены как extern сами по себе...
Вот именно что основы я понимаю, знаю и понимаю ООП. Но основная среда разработки у меня другая. Все мои примеры основаны на опыте работы с Delphi, а там мои примеры которые выше, но адаптированные под С++, считаются логичными и не вызывают никаких проблем и накладных расходов... Для меня вся проблема только в неожиданных"сюрпризах", "хитрых" директивах и структуре проекта...
Да не требуется там extern перестает компилироваться тогда. По ощущениям эти классы уже объявлены как extern сами по себе...
Вот именно что основы я понимаю, знаю и понимаю ООП. Но основная среда разработки у меня другая. Все мои примеры основаны на опыте работы с Delphi, а там мои примеры которые выше, но адаптированные под С++, считаются логичными и не вызывают никаких проблем и накладных расходов... Для меня вся проблема только в неожиданных"сюрпризах", "хитрых" директивах и структуре проекта...
Нет, не так. В h-файлах ничего не должно создаваться. Там только описание того, что модуль даёт на экспорт.Из всего сказанного понял и сделал отдельный модуль:
Всё созданное лежит в c-файлах модулей.
display.h
Код: Выделить всё
#ifndef DISPLAY_H
#define DISPLAY_H
#include <Arduino.h>
#include "U8glib.h"
U8GLIB_ST7920_128X64_1X* GetDisplayPtr(void);
#endifКод: Выделить всё
#include "display.h"
static U8GLIB_ST7920_128X64_1X Display;
U8GLIB_ST7920_128X64_1X* GetDisplayPtr(void)
{
return(&Display);
}
extern там можно. Работать будет. Можно даже extern функций делать. Вы просто ещё не освоились с концепцией заголовок-реализация. Поэтому ставите extern не туда и подключаете не то (и создали, наверняка, объект в заголовочном файле). Но это плохой стиль. Приводит он к тому, что у вас состояние модуля (речь не о вашем классе дисплея - тут это действительно пофигу, он у вас один, но вот в будущем не привыкайте к такому стилю) меняется с разных точек. А если вы измените поведение? А если оно начнёт меняться непредсказуемо? Вот поэтому глобальные переменные вредны. Их стоит использовать разве что при ну очень жесткой экономии ресурсов.Да не требуется там extern перестает компилироваться тогда. По ощущениям эти классы уже объявлены как extern сами по себе...
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]Да не требуется там extern перестает компилироваться тогда.[/uquote]Ну не требуется так не требуется. Трахайтесь дальше вместо того чтобы одну страницу по ссылке про extern изучить.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]По ощущениям эти классы уже объявлены как extern сами по себе...[/uquote] Ещё бы понятие класс и объект научиться отличать.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]Вот именно что основы я понимаю, знаю и понимаю ООП.[/uquote]Это видно, по тому как лихо вы объекты копируете и из/в функции передаёте.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]Все мои примеры основаны на опыте работы с Delphi,[/uquote]Ну ничего не поделаешь, взялись за С++, будьте добры изучить и подчиняться его правилам.
Добавлено after 4 minutes 24 seconds:
[uquote="da-nie",url="/forum/viewtopic.php?p=3832702#p3832702"]Вот поэтому глобальные переменные вредны. Их стоит использовать разве что при ну очень жесткой экономии ресурсов.[/uquote]Тут не просто переменные, а объект неизвестного размера. Где же его ещё создавать, не в стеке или куче же. Да ещё чтобы доступен из других единиц трансляции был.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]По ощущениям эти классы уже объявлены как extern сами по себе...[/uquote] Ещё бы понятие класс и объект научиться отличать.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]Вот именно что основы я понимаю, знаю и понимаю ООП.[/uquote]Это видно, по тому как лихо вы объекты копируете и из/в функции передаёте.
[uquote="matrex",url="/forum/viewtopic.php?p=3832700#p3832700"]Все мои примеры основаны на опыте работы с Delphi,[/uquote]Ну ничего не поделаешь, взялись за С++, будьте добры изучить и подчиняться его правилам.
Добавлено after 4 minutes 24 seconds:
[uquote="da-nie",url="/forum/viewtopic.php?p=3832702#p3832702"]Вот поэтому глобальные переменные вредны. Их стоит использовать разве что при ну очень жесткой экономии ресурсов.[/uquote]Тут не просто переменные, а объект неизвестного размера. Где же его ещё создавать, не в стеке или куче же. Да ещё чтобы доступен из других единиц трансляции был.
- Сообщения: 28
- Зарегистрирован: Сб ноя 24, 2012 14:02:39
A!!! Все ясно. Нет ничего лучше, как своевременный пример по делу. Все сразу стало на свои места. С правильным подходом удалось сэкономить еще и сотню байт. Спасибо.
Так я несколько не об этом. Я имел в виду, что эту переменную нужно запирать в модуле, чтобы её не было видно глобально во всей программе.Тут не просто переменные, а объект неизвестного размера. Где же его ещё создавать, не в стеке или куче же. Да ещё чтобы доступен из других единиц трансляции был.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="da-nie",url="/forum/viewtopic.php?p=3832796#p3832796"]Так я несколько не об этом. Я имел в виду, что эту переменную нужно запирать в модуле, чтобы её не было видно глобально во всей программе.[/uquote]Зачем? Это глобальный ОБЪЕКТ - экран. Работа с ним осуществляется через его методы. Что там ещё прятать? Всё и так внутри объекта. То что автор решил его тягать как обычную переменную по функциям... Ну это он ССЗБ.
Вот это и прятать.То что автор решил его тягать как обычную переменную по функциям... Ну это он ССЗБ.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: 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
А кстати, в плюсах если объект передавать как указатель в аргументах функции, накладных расходов же будет?
Добавлено after 1 minute 53 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=3832683#p3832683"]В arduino ide компилятор gcc, который С++ только в путь. Сам по себе C++ не даёт накладных расходов, если с головой подходить, а не так как matrex.[/uquote]
Не просто в путь. Весь Arduino Core (те самые библиотеки, на которых все строится в ардуино) основан на плюсах с ооп. Тот же Serial - объект. И многие другие вещи классами описаны.
Добавлено after 1 minute 53 seconds:
[uquote="VladislavS",url="/forum/viewtopic.php?p=3832683#p3832683"]В arduino ide компилятор gcc, который С++ только в путь. Сам по себе C++ не даёт накладных расходов, если с головой подходить, а не так как matrex.[/uquote]
Не просто в путь. Весь Arduino Core (те самые библиотеки, на которых все строится в ардуино) основан на плюсах с ооп. Тот же Serial - объект. И многие другие вещи классами описаны.
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="NStorm",url="/forum/viewtopic.php?p=3832871#p3832871"]А кстати, в плюсах если объект передавать как указатель в аргументах функции, накладных расходов же будет?[/uquote]В этом случае передаётся не "объект как указатель", а указатель. Накладные будут при доступе по этому указателю. Насколько большие зависит от архитектуры. При развитых типах адресации может и не быть накладных.
Не должно быть. Когда вызывается функция класса, ей так или иначе передаётся указатель на класс. Исключение - статические функции.Накладные будут при доступе по этому указателю.
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: 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
Ну раз пошел у нас такой задушевный диалог, разрешите еще вопрос. Как правильно инициализировать структуру (по сути массив) нулями. В идеале одной командой сразу всю.
Делаю "в лоб" (работает, но не изящно, знаю что можно лучше):
Пытаюсь через memset (в начале вроде как работало, но потом из-за того что похоже подход не верный, начали разрушаться переменные):
В итоге - никак не инициализирую массив (все работает, экономит десяток байт) - вроде как из спецификации CPP там должны находиться нули по умолчанию, но меня терзают сомнения, а предыдущий опыт говорит о том, что переменные лучше инициализировать явно во избежании лишних проблем.
Код: Выделить всё
// данные с датчиков
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); а вот так не в лоб?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));
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[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"][/uquote]На ARM нужно 10 раз подумать прежде чем так делать, чтобы исключить невыровненный доступ там где его нет и в HardFault не улететь. Можно, но с головой!
Добавлено after 2 minutes 45 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3833003#p3833003"]
Код: Выделить всё
memset(&dt, 0, sizeof(rSENSORS));
- Сообщения: 1978
- Зарегистрирован: Ср июл 17, 2013 13:55:57
А зачем вы создали структуру из массивов? У вас же размерность одинаковая. Сделайте массив структур.
Если уже отличное от нулей, то тогда можно делать так:
Можно в т.ч. написать = { 0 }.
Или сделать уже memset(dt, 0, sizeof dt);. Одна инструкция, а не для каждого члена структуры, как у вас.
Песочница: https://godbolt.org/z/2JgWai
Если настаиваете на вашей структуре с массивами, то тогда можно и так обнулять:
Код: Выделить всё
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 };
Или сделать уже memset(dt, 0, sizeof dt);. Одна инструкция, а не для каждого члена структуры, как у вас.
Песочница: https://godbolt.org/z/2JgWai
Если настаиваете на вашей структуре с массивами, то тогда можно и так обнулять:
Код: Выделить всё
dt = (struct rSENSORS){ 0 };
Последний раз редактировалось NStorm Пн апр 27, 2020 12:48:09, всего редактировалось 1 раз.
было бы конструктивно объяснить, как следует поступать, чтобы не нарваться. причем без привзяки к ARM, а вообще по правильному для С++, раз уж тема об этом языке.VladislavS писал(а):На ARM нужно 10 раз подумать прежде чем так делать, чтобы исключить невыровненный доступ там где его нет и в HardFault не улететь.
это чем-то отличается от предложенного мной?NStorm писал(а):Или сделать уже memset(dt, 0, sizeof dt);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


