Страница 330 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 10:12:22
ПростоНуб
Eddy_Em, это считается ненадежным кодом, в принципе, обосновано (объяснять, надеюсь, не надо?). Но на МК, когда подобный подход позволяет экономить столь дефицитный стек - вполне оправдано.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 10:42:32
jcxz
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3712465#p3712465"]jcxz, если бы Вы умели читать, то обнаружили бы[/uquote]А если бы вы научились думать, то догадались бы что написанное мной:
От варнингов нужно избавляться всегда.
Это именно то, что Вы потом и делаете подавляете предупреждение.
Так с чем Вы несогласны??? Избавляться от варнингов - это правильно или нет? Я написал что "правильно", вы ответили "не согласен". А потом в примере начале приводить способы "убирания".
Где логика?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 10:48:55
ПростоНуб
[uquote="jcxz",url="/forum/viewtopic.php?p=3712500#p3712500"]От варнингов нужно избавляться всегда.
Это именно то, что Вы потом и делаете подавляете предупреждение.[/uquote]
По Вашей же логике, тогда можно навсегда избавиться от предупреждений, просто подавив их всех в командной строке компилятора )))
Если у Вас вырос чирий и Вы его заклеили лейкопластырем, то Вы от него избавились или просто скрыли его от глаз? )))
Подавление предупреждение не избавляет от предупреждения, а только подавляет его вывод. Странно, что Вы не замечаете разницы. Напоминаете страуса )))
"Видишь суслика? - Нет. - И я не вижу. А он есть!" (с)
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 12:58:04
jcxz
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3712503#p3712503"]По Вашей же логике, тогда можно навсегда избавиться от предупреждений, просто подавив их всех в командной строке компилятора )))[/uquote]Да, можно и так. Если уверен в своих действиях. Я, например, знаю, что я понимаю разницу между операторами '=' и '==', поэтому всегда отключаю варнинг "вы написали '=', но возможно хотели '=='" во всех проектах во компиляторах сразу.
В других случаях (при приведении типов например), делаю явное приведение типов. Что говорит мне же в последующем, при чтении исходника, что это приведение делается здесь преднамеренно и ошибки нет.
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3712503#p3712503"]Подавление предупреждение не избавляет от предупреждения, а только подавляет его вывод. Странно, что Вы не замечаете разницы. Напоминаете страуса )))[/uquote]Вы сами-то не видите абсурдности этой фразы?
Предупреждение - это сообщение, всего-лишь. Подавление его - оно же отключение, не выдача этого сообщения.
Или вы боитесь, что если заставили компилятор замолчать, то он всё равно продолжает про себя в уме плохо думать о вас. И предупреждает другие программы на компе "Вот какой плохой парень тут у нас сидит - затыкает мне рот!"
От таких постов уже не страусом попахивает, а паранойей
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3712503#p3712503"]"Видишь суслика? - Нет. - И я не вижу. А он есть!" (с)[/uquote] Надеюсь подскажут вам куда следует обращаться когда видишь то, чего нет.

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 13:21:29
Ivanoff-iv
Точней - куда обращаться, когда не видишь то, что есть.
В машине есть лампочка неисправности двигателя, когда она загорится, один чинит мотор, другой ездит с ней дальше, а третий лампочку вывернет - и нет проблемы ...

Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 14:42:21
ПростоНуб
[uquote="jcxz",url="/forum/viewtopic.php?p=3712596#p3712596"]Вы сами-то не видите абсурдности этой фразы?[/uquote]
ПростоНуб писал(а):Если у Вас вырос чирий и Вы его заклеили лейкопластырем, то Вы от него избавились?
Я вижу. Вы так все болезни лечите? )))
Добавлено after 38 minutes 56 seconds:
[uquote="jcxz",url="/forum/viewtopic.php?p=3712596#p3712596"][uquote="ПростоНуб",url="/forum/viewtopic.php?p=3712503#p3712503"]"
Видишь суслика? -
Нет. - И
я не вижу. А он есть!" (с)[/uquote] Надеюсь подскажут вам куда следует обращаться
когда видишь то, чего нет.

[/uquote]
Это зачет! Вы про себя что ли? )))
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт окт 04, 2019 22:21:27
ARV
jcxz писал(а):От варнингов нужно избавляться всегда.
Это именно то, что Вы потом и делаете подавляете предупреждение.
если бы я был профессиональным программистом, вы бы наверняка обратили внимание на мои слова... но я не он, и потому повторюсь: избавляться от варнингов, по моему мнению, в большинстве случаев совсем нет необходимости. просто надо как-то научиться с этим жить

я вот избавляюсь только от варнингов о потенциальной угрозе, например, когда я и в самом деле по запарке забыл дописать лишний знак = или (все чаще и чаще - клава сбоит) пропустил какой-то символ при вводе...
jcxz писал(а):Избавляться от варнингов - это правильно или нет?
это никак. точнее, это "как" только в каждом отдельно рассматриваемом случае. а абстрактно - никак вообще.
Добавлено after 4 minutes 46 seconds:
jcxz писал(а):Я, например, знаю, что я понимаю разницу между операторами '=' и '==', поэтому всегда отключаю варнинг "вы написали '=', но возможно хотели '=='" во всех проектах во компиляторах сразу.
и вот я бы посмотрел на вас после того, как у вас, как у меня на ноуте, разочек клава сбойнула и вместо == у вас прошел бы = без варнинга

Re: Вопросы по С/С++ (СИ)
Добавлено: Вс дек 15, 2019 22:50:13
uldemir
Снова проблема. Keil uVision, Таргет MSP432P401H.
...И вот я случайно обнаруживаю, что на дисплейчике одна надпись отображается неправильно. Смотрю исходники - правильно. Захожу с отладчиком - неправильно. Прохожу отладчиком - всё правильно. Запускаю под отладчиком Run - неправильно. Ага, какое-то прерывание гадит в память. Искал-искал - ничего не нашел, а тут глянул случайно и... ничего не понимаю. В одном файле, configure.c есть автоматическая переменная. большая.
Спойлер
Код: Выделить всё
typedef enum {select_mode, edit_mode} mode_t;
mode_t mode = select_mode;
typedef enum {none, decimal, hex, hex32} datatype_t;
typedef struct {
unsigned char todisplay[16];
int *variable;
datatype_t datatype;
} menuitem_t;
menuitem_t menu_item[] = {
{"PathLength xxxxx", &data.pathlength, decimal},
{"Loop Num xxxxx", &data.loop, decimal},
{"RunNumber xxxxx", &data.runnumber, decimal},
{"Map size xxxxx", &data.map_size, decimal},
{"Save&Exit ", 0, none},
{"Threshold xxxxx", &data.threshold, decimal},
{"IR level xxxxx", &data.ir_led_level, decimal},
{"On Way xxxxx", &data.on_way, decimal},
{"MAXmotor xxxxx", &data.maxmotor, decimal},
{"MAX speed xxxxx", &data.maxspeed, decimal},
{"MIN speed xxxxx", &data.minspeed, decimal},
{"Turn speed xxxxx", &data.turnspeed, decimal},
{"Accelerat xxxxx", &data.acceleration, decimal},
{"K*error xxxxx", &data.k_error, decimal},
{"K*de/dt xxxxx", &data.k_diff, decimal},
{"Sigma div xxxxx", &data.div_sigma, decimal},
{"Left Hand xxxxx", &data.lefthand, decimal},
И там еще дальше есть. Так вот в данный момент теряется буква L в названии Left Hand. Она находится по адресу 0x20001B40
и тут я случайно замечаю, что её адрес накрывает переменную из другого файла - Tachometr.c
TachLeft 0x20001b38
TachRight 0x20001b44
Код: Выделить всё
typedef struct {
uint16_t Period;
int Steps;
enum TachDirection Dir;
} Tach_stru_t;
volatile Tach_stru_t TachLeft, TachRight;
Это получается, что я получил переполнение стека?? Но при компиляции мне никто никаких предупреждений не выдал. Что делать и как этого избежать в дальнейшем?
Добавлено after 45 minutes:
Вообще-то, menu_item - это константная структура и ей в ОЗУ делать нечего. Как её заставить разместиться в ПЗУ? модификатора const будет достаточно?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс дек 15, 2019 23:30:55
Z_h_e
uldemir писал(а):Вообще-то, menu_item - это константная структура и ей в ОЗУ делать нечего. Как её заставить разместиться в ПЗУ? модификатора const будет достаточно?
По-моему да, компил кейла наверняка в память программ засунет, но лучше проверить.
uldemir писал(а):Это получается, что я получил переполнение стека?? Но при компиляции мне никто никаких предупреждений не выдал. Что делать и как этого избежать в дальнейшем?
Наверное же есть файл стартапа? Поглядите как там инициализация указателя стека оформлена. Я уже сталкивался и это обсуждалось в ARMом разделе, что по умолчанию в стартапе указаетель инициализируется вовсе на конец памяти. MSP432 я совсем не знаю, если что

.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 01:08:01
WiseLord
Что-то мне кажется, что unsigned char todisplay[16] недостаточно для хранения тех строк. У них у всех длина 17 (с учётом конца строки).
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 06:44:21
uldemir
Хм. Про null-terminated я как-то и позабыл. Но, похоже, что компилятор понял, что я хотел. Вот уже переволок в ПЗУ. помимо const пришлось еще и вытащить наружу из функции (сделать глобальной).

Надо сделать ревизию по проекту, может еще где такая плюха всплывёт. А то на прошлой неделе уже
ловил в этом проекте GPF, может это и было причиной (Потому как, снова, таходатчик оказался замешан)?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 09:43:42
WiseLord
Компилятор, скорее всего, этот 17-й 0 просто перезаписывает следующим элементом структуры (указателем), так что оно, казалось бы, ничего страшного. Но тогда функция вывода на экран уже не может опираться на то, что это строка (на null-терминатор), а должна быть искусственно ограничена при выводе 16-ю символами.
А вообще хороший компилятор должен об этом, как минимум, предупредить. А лучше бы выставить такие флаги компиляции, чтобы вообще всё летело в ошибки.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 17:52:46
uldemir
Если добавить еще один символ, предупреждение выдается. И я не пользуюсь функциями вывода. это всё копируется ручками в экранную область.
в startupе нашел только размер стека. в репорте - адрес. Приеду домой, посмотрю в книжке, куда у этих кортексов растет стек, вверх или вниз по адресам?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 18:01:47
Z_h_e
uldemir писал(а):в startupе нашел только размер стека. в репорте - адрес. Приеду домой, посмотрю в книжке, куда у этих кортексов растет стек, вверх или вниз по адресам?
Нормально там все, вниз как у всех.
https://radiokot.ru/forum/viewtopic.php ... 0%B5%D0%BA
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 16, 2019 19:51:22
uldemir
Ну, тогда, я начал понимать что означают эти цифры в репорте.
Код: Выделить всё
videobuffer 0x200004d0 Data 128 configure.o(.bss)
.bss 0x20000550 Section 912 main.o(.bss)
.bss 0x200008e0 Section 4500 maze.o(.bss)
.bss 0x20001a74 Section 24 tachometer.o(.bss)
.bss 0x20001a8c Section 96 libspace.o(.bss)
HEAP 0x20001af0 Section 0 startup_msp432p401r_uvision.o(HEAP)
STACK 0x20001af0 Section 512 startup_msp432p401r_uvision.o(STACK)
Heap_Mem 0x20001af0 Data 0 startup_msp432p401r_uvision.o(HEAP)
Stack_Mem 0x20001af0 Data 512 startup_msp432p401r_uvision.o(STACK)
__initial_sp 0x20001cf0 Data 0 startup_msp432p401r_uvision.o(STACK)
В стартапе было написано, что размер стека 512 байт (это всего 128 элементов можно положить?). Вот только не нашел, где бы в настройках это можно было бы изменить. Ну, зато я могу в остальном ОЗУ забабахать буфер для отладочной информации.
Главное, проблему понял. Все эти длинные наборы данных перетащил в ПЗУ. Спасибо за разъяснения.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт дек 26, 2019 20:02:52
uldemir
нашел еще место, где у меня не хватает памяти в стеке. Хоть я его и увеличил с 0x200 до 0x800 одна функция хапает память. И вот допустим, я хочу ей выделить память в куче.
я так понимаю, что надо звать malloc и оно вернёт мне указатель на эту память. Вопрос первый, как вычислить размер требуемой памяти?
Код: Выделить всё
map_cell_t map[100]; // для этого надо выделить память.
//а вот их определение:
typedef struct coordinate{
int east;
int north;
} coordinate_t;
typedef struct {
struct coordinate coordinate;
unsigned int node_link[4];
unsigned int pass_count[4];
} map_cell_t;
Так то я могу прикинуть, что один элемент таблицы требует 40 байт, значит 100 => 4000 байт. Но как это написать так, чтобы если я изменю структуру, всё-равно выделялось бы правильно.
Ну и второй вопрос, как этот массив там разместить так, чтобы я мог с этими элементами работать как с массивом через индексы? например, вот так:
Код: Выделить всё
for (i=0; i<data.map_size; i++) {
if (map[i].coordinate.north > maxY) maxY = map[i].coordinate.north;
if (map[i].coordinate.north < minY) minY = map[i].coordinate.north;
if (map[i].coordinate.east > maxX) maxX = map[i].coordinate.east;
if (map[i].coordinate.east < minX) minX = map[i].coordinate.east;
}
ok, с первым вроде понятно - malloc(sizeof(map_cell_t)*100);
Но вот со вторым... совсем не понятно как поступить, так как через указатели - придётся весь код переписывать.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт дек 26, 2019 21:06:48
Мурик
uldemir писал(а):нашел еще место, где у меня не хватает памяти в стеке. Хоть я его и увеличил с 0x200 до 0x800 одна функция хапает память. И вот допустим, я хочу ей выделить память в куче.
В куче есть лишняя память?
Объявите массив глобальным (или статическим если работа в одной функции) или увеличьте стек чтобы в него все поместилось.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт дек 26, 2019 21:42:47
uldemir
Как обойти проблему - я знаю. просто хочу научиться использовать еще один метод. В куче место должно быть - я ею никогда раньше не пользовался (и stdlib.h нигде не подключал). Да и данная функция не критичная - всего-навсего отрисовывает карту на экране. Если для этого не хватит памяти - не беда. А вот из-за того, что стек налазит куда не нужно, у меня при отрисовке мотор дёргается - это хуже.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт дек 26, 2019 21:49:03
NStorm
Первое - правильно. Второе как-то так:
Код: Выделить всё
map_cell_t *map = malloc(sizeof(map_cell_t)*100);
Но это только выделит память на структуру. На сами элементы тоже придется выделять:
Код: Выделить всё
int i;
for(i = 0; i < 100; ++i)
map[i] = malloc(sizeof *map[i]);
Но вообще динамическое распределение памяти и куча на МК - очень плохая идея.
Добавлено after 5 minutes 29 seconds:
В куче место должно быть
Эмм... значит и для стека место должно быть )

Re: Вопросы по С/С++ (СИ)
Добавлено: Чт дек 26, 2019 22:05:53
uldemir
Пройдите по ссылке из этого сообщения
https://radiokot.ru/forum/viewtopic.php ... 7#p3756997 Там есть тема, с которой я тоже сейчас борюсь. Почему-то Keil вершину стека ставит через 512 байт (по умолчанию) после последней переменной, оставляя память над стеком и до конца ОЗУ совершенно пустой. И, компилятор, почему-то совершенно не предупреждает или как-то иначе указывает, что размера стека недостаточно для автоматических переменных. Вот теперь выяснилось, что увеличение стека с 0x200 до 0x800 мало - один этот массив отъедает в два раза больше памяти (как выяснилось). Собственно, мне даже такой большой массив и не нужен - пока карты у меня имели размеры от 12 до 28 элементов. Поэтому и интересно выделить столько сколько нужно, а не все 100 элементов.