Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]планирую инициализировать все поля структуры y одинаковой строкой[/uquote]надо каждое поле и инициализировать
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]получаю варнинг[/uquote]странно, у меня оно без варнингов собирается (gcc 6.5.0, 7.4.0, 8.2.0; -Wall)
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]инициализируется только первое поле структуры[/uquote]так и должно быть
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]получаю варнинг[/uquote]странно, у меня оно без варнингов собирается (gcc 6.5.0, 7.4.0, 8.2.0; -Wall)
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]инициализируется только первое поле структуры[/uquote]так и должно быть
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]планирую инициализировать все поля структуры y одинаковой строкой[/uquote]планировать мало, нужно сделать
Ваш код инициализирует только первый элемент. Наверное, Вы по аналогии с решили, что всё проинициализируется "1"?
"Omitted fields are implicitly initialized the same as for objects that have static storage duration."
Предупреждение возникает, предположительно, из-за того, что элементы структуры тоже являются массивами. Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
Код: Выделить всё
my_t var = {0};"Omitted fields are implicitly initialized the same as for objects that have static storage duration."
Предупреждение возникает, предположительно, из-за того, что элементы структуры тоже являются массивами. Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
да, а разве я не прав? ведьAAX писал(а):решили, что всё проинициализируется "1"?
Код: Выделить всё
int arr[100] = {7};
struct var { int a; int b; int c} = {7};у меня по умолчанию -WallAAX писал(а): Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Нет, конечно. С чего бы ?ARV писал(а):для структур правило "для всех" не действует?
Проинициализируется только первое поле структуры.
Такое правило (инициализация всех ячеек одним значением) только для массивов. В структурах могут быть разные типы полей, по этому подобное правило было бы нелогичным.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
ЕМНИП, и для массива - нет. Только первый элемент, остальные - нулями.ARV писал(а):проинициализирует все элементы и поля семерками... или нет?
Для GCC можно ещё '...' использовать для указания диапазона.
В любом случае, любые попытки инициализировать элементы чем-то, отличным от нуля, будут увеличивать размер прошивки, тем больше, чем больше элементов в массиве, структуре и т.д.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
мда... как обманчива природа... спасибо за науку.Аlex писал(а):Такое правило (инициализация всех ячеек одним значением) только для массивов
в моём случе речь об инициализации EEPROM, так что ничего увеличиваться не будет.WiseLord писал(а):В любом случае, любые попытки инициализировать элементы чем-то, отличным от нуля, будут увеличивать размер прошивки
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="WiseLord",url="/forum/viewtopic.php?p=3545811#p3545811"]ЕМНИП, и для массива - нет. Только первый элемент, остальные - нулями.[/uquote]
Неохота искать источники, но я так тоже всегда считал. А значит откуда то вбилось.)
Неохота искать источники, но я так тоже всегда считал. А значит откуда то вбилось.)
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3545804#p3545804"]
Это руководство GCC.
[uquote="ARV",url="/forum/viewtopic.php?p=3545804#p3545804"]
Мкей, тогда давайте так: -Wall не включает всех возможных предупреждений. С настройками по-умолчанию (-Wall) приведённая Вами конструкция не вызывает появления каких-либо предупреждений при компиляции при помощи gcc version 5.4.0 (AVR_8_bit_GNU_Toolchain_3.6.0_1734)
да, а разве я не прав?[/uquote]я ж ссылку дал. Можно было бы за минуту прочесть, и понять, прав-не прав... Это ж не википедияAAX писал(а):решили, что всё проинициализируется "1"?
[uquote="ARV",url="/forum/viewtopic.php?p=3545804#p3545804"]
у меня по умолчанию -Wall[/uquote]Вы, наверное, решили, что опция -Wall включает все возможные предупреждения компилятора? This enables all the warnings about constructions that some users consider questionable. Впрочем, ходить по ссылкам, читать - скукота... гораздо лучше положиться на мнение неизвестного человека из интернетов, с вероятностью 95% - бестолкового, т.к. "толковым" в интернетах отвисать некогдаAAX писал(а): Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
всегда перед тем, как задать вопрос на форуме, пытаюсь найти ответ в доступных мне источниках, в частности, при помощи поиска в googleAAX писал(а):Это руководство GCC
в том-то и дело, что от версии к версии avr-gcc меняет своё поведение "по умолчанию". в документации тоже не всегда легко найти особенности именно этой версии. но главное - невозможно понять, почему именно так, а не иначе "было-стало". и в этом случае обращаюсь на форум.AAX писал(а):приведённая Вами конструкция не вызывает появления каких-либо предупреждений при компиляции при помощи gcc version 5.4.0
вы сейчас себя имели ввиду?AAX писал(а):гораздо лучше положиться на мнение неизвестного человека из интернетов, с вероятностью 95% - бестолкового
указанные мной версии компилятора выдают указанные мною предупреждения, и ведут себя так, как я описал. хоть я и имею набор версий от 3.х.х. до 8.х.х, проверять каждую как-то лень. причина "странной" на мой взгляд инициализации структур мне уже стала понятна - спасибо "бестолковым", кто уже успел мне объяснить. причина появления варнингов - не понятна до сих пор, как не понятен до сих пор и способ избавления от них (не считая отключения опции) без необходимости инициализировать каждое поле принудительно.
пока это всё.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3549882#p3549882"]причина появления варнингов - не понятна до сих пор[/uquote]глюк конкретной версии?
Спойлер
Код: Выделить всё
arkhnchul@arkhost-scow:/tmp$ cat tst1.c
#define CNT 10
typedef struct{
char about_a[CNT];
char about_f[CNT];
char about_d[CNT];
char about_i[CNT];
char about_t[CNT];
} n_t;
typedef struct{
int x;
n_t y;
}my_t;
my_t var = {
.x = 12,
.y = {"1"}
};
int main(){
return 0;
}
arkhnchul@arkhost-scow:/tmp$ avr-gcc -Wall -Wmissing-braces -c -S tst1.c
arkhnchul@arkhost-scow:/tmp$ avr-gcc --version
avr-gcc (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3549882#p3549882"]вы сейчас себя имели ввиду?
[/uquote]в том числе и себя, конечно.
Если человек высказывает мнение по обсуждаемому вопросу, обычно следует поинтересоваться источником его знания. И ознакомиться с ним, т.к. 1) люди не всегда формулируют точно, мануалы и учебники пишут лучше. Ну, и просто - при каждом пересказе информации свойственно искажаться. 2) человек, обычно, высказывается только о предмете, вызвавшем обсуждение. В мануале или в учебнике есть шанс получить дополнительное полезное знание, о вещах, не упомянутых в контексте данного обсуждения.
Даже если Вам повезло, и Вы встретились (чудом) в интернетах с "толковым" человеком, у него наверняка не будет времени вникать в нюансы Вашего вопроса и разжёвывать ответ. Это как у линуксоидов когда-то было принято: вместо ответа на вопрос отправлять читать нужный man.
Если человек высказывает мнение по обсуждаемому вопросу, обычно следует поинтересоваться источником его знания. И ознакомиться с ним, т.к. 1) люди не всегда формулируют точно, мануалы и учебники пишут лучше. Ну, и просто - при каждом пересказе информации свойственно искажаться. 2) человек, обычно, высказывается только о предмете, вызвавшем обсуждение. В мануале или в учебнике есть шанс получить дополнительное полезное знание, о вещах, не упомянутых в контексте данного обсуждения.
Даже если Вам повезло, и Вы встретились (чудом) в интернетах с "толковым" человеком, у него наверняка не будет времени вникать в нюансы Вашего вопроса и разжёвывать ответ. Это как у линуксоидов когда-то было принято: вместо ответа на вопрос отправлять читать нужный man.
Re: Вопросы по С/С++ (СИ)
[uquote="WiseLord",url="/forum/viewtopic.php?p=3545811#p3545811"]...
Только первый элемент, остальные - нулями....[/uquote]
В данном случае только первый элемент. Заполнять остальное нулями компилятор не обязан. Чистка буфера до обмена в Си всегда отдавалась на откуп программисту. И это правильно.
Только первый элемент, остальные - нулями....[/uquote]
В данном случае только первый элемент. Заполнять остальное нулями компилятор не обязан. Чистка буфера до обмена в Си всегда отдавалась на откуп программисту. И это правильно.
- da-nie
- Говорящий с текстолитом
- Сообщения: 1590
- Зарегистрирован: Вс июн 24, 2012 16:07:00
- Откуда: Лен.Обл.
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
А вот интересно, если написать static int Buffer[100], компилятор заполнит буфер нулями? Вообще, должен - инициализация статических переменных нулями гарантируется.
И день и ночь в пути...
Мои программки: 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
Re: Вопросы по С/С++ (СИ)
А неинициализированные глобальные переменные (в т.ч. и массивы) разве не обнуляются компилятором, стартап секцией?
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Статические точно обнуляются, а глобальные, как отметил shindax, в принципе, не обязательно, но практически наверняка, компилятор их оптимизирует подобно статическим. По крайней мере, в случае avr-gcc и типичных флагах компиляции (-Os) разницы между прошивками, где глобальные массивы объявлены как static, и прошивками, где - не static, никакой нет.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
глобальные переменные, т.е. не являющиеся локальными, компилятор всегда обнуляет наравне со статическими, в этом сомнений нет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ROMan2947
- Грызет канифоль
- Сообщения: 287
- Зарегистрирован: Сб янв 23, 2016 00:59:59
- Откуда: Чебоксары
Re: Вопросы по С/С++ (СИ)
здравствуйте! проблема с кодом, выложить пока не могу, т. к. не рядом с компом. но и не могу успокоиться найдя проблему.суть вот в чем:в целом код работал, после незначительных, на мой взгляд, манипуляции с переменными он перестал выполнять свои функции. пытался отладчиком отловить баг, но не смог. компилируется чисто, при отладке в дис. коде вижу что происходит сброс PC(rjump PC 0*0000) . Подскажите пожалуйста, почему эта гадость могла возникнуть, где копать?
- da-nie
- Говорящий с текстолитом
- Сообщения: 1590
- Зарегистрирован: Вс июн 24, 2012 16:07:00
- Откуда: Лен.Обл.
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Варианты, когда код перестаёт работать после незначительного изменения:
1) Вы не использовали volatile там где надо.
2) У вас утечка памяти.
3) Вы выходите за пределы массивов.
4) В коде связанные переменные, находящиеся в разных модулях - изменился порядок инициализации.
Советую скачать cppcheck (он бесплатный) http://cppcheck.sourceforge.net/ и проверить им программу.
1) Вы не использовали volatile там где надо.
2) У вас утечка памяти.
3) Вы выходите за пределы массивов.
4) В коде связанные переменные, находящиеся в разных модулях - изменился порядок инициализации.
Советую скачать cppcheck (он бесплатный) http://cppcheck.sourceforge.net/ и проверить им программу.
И день и ночь в пути...
Мои программки: 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
- ROMan2947
- Грызет канифоль
- Сообщения: 287
- Зарегистрирован: Сб янв 23, 2016 00:59:59
- Откуда: Чебоксары
Re: Вопросы по С/С++ (СИ)
[uquote="da-nie",url="/forum/viewtopic.php?p=3551245#p3551245"]Варианты, когда код перестаёт работать после незначительного изменения[/uquote] спасибо,покопаюсь. из всего Вами перечисленного утечка памяти особо привлекло внимание.Такое понятие в микроконтроллерах я еще не слышал.
Кстати вот собственно и код:
Добавлено after 1 hour 3 minutes 21 second:
[uquote="da-nie",url="/forum/viewtopic.php?p=3551245#p3551245"]Советую скачать cppcheck[/uquote] хороший инструмент,необходимая вещь для новичка!отсканировал свой косячный код выдало несколько явных ошибок и одну сомнительную,все исправил и заработало. Спасибо большое,сегодня спать хоть буду спокойно
Кстати вот собственно и код:
Спойлер
Код: Выделить всё
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "LCD.h"
#define ds18b20_DDR DDRB
#define ds18b20_PORT PORTB
#define ds18b20_PIN PINB
#define DQ 1
#define BIT_PORT PORTB
#define BIT_DDR DDRB
#define BIT_PIN PINB
#define BIT_ANALISATOR 0
#define SEARCH_ROM 0xF0 // ПОИСК РОМ
#define READ1_ROM 0x33 //ЧТЕНИЕ РОМ ПРИ ОДНОМ ДАТЧИКЕ НА ШИНЕ
#define MATCH_ROM 0x55 // СООТВЕТСТВИЕ РОМ
#define SKIP_ROM 0xCC // ПРОПУСК РОМ
#define ALARM_SEARCH_ROM 0xEC //ПОИСК ТРЕВОГ
#define CONVERT_TEMPERATUR 0x44 //КОНВЕРТРВАНИЕ ТЕМПЕРАТУРЫ
#define WRITE_ROM 0x4E //ЗАПИСЬ В ПАМЯТЬ ТРИ БАЙТА
#define READ_MEMORY 0xBE //ЧТЕНИЕ ПАМЯТИ
#define COPY_ROM 0x48 //КОПИРОВАНИЕ ДАНЫХ ИЗ РОМ В ПЗУ
#define BUS_HIGT ds18b20_DDR&=~(1<<DQ);
#define BUS_LOW ds18b20_DDR|=1<<DQ;
#define resolution 0.0625
uint8_t bit=0x00;
uint64_t ID_ds18b20=0;
char DATA_ROM_string1[16]={0};
uint8_t DATA_REGISTR = 0;
uint8_t i = 0;
uint64_t MEMORY_ds18b20;
uint8_t CRC_calculate;
int16_t temperatura=0;
void print (char *data)
{
write_command(clear_display);
write_command(0x80);
for(uint8_t x=0; data[x]!='\0';x++)
{
write_data(data[x]);
}
_delay_ms(100);
}
void convert_data(uint8_t massiv)
{
sprintf(DATA_ROM_string1, "%x", massiv);
print(DATA_ROM_string1);
}
uint64_t read_bit(void)
{
bit=0x00;
BUS_LOW;
_delay_us(3);
BUS_HIGT;
_delay_us(15);
if(ds18b20_PIN&(1<<DQ))
bit=0x01;
_delay_us(60);
return bit;
}
void ds18b20_init(void)
{
ds18b20_PORT&=~(1<<DQ);
BUS_LOW;
_delay_us(480);
BUS_HIGT;
_delay_us(35);
if((ds18b20_PIN&(1<<1))==0)
{
_delay_us(480);
}
else
{
_delay_us(480);
}
}
void write_ds18b20(uint8_t data)
{
ds18b20_PORT&=~(1<<DQ);
for (uint8_t i=0;i<=7;i++)
{
BUS_HIGT;
_delay_us(15);
if(data&(1<<i))
{
BUS_LOW;
_delay_us(5);//////
BUS_HIGT;
}
else
{
BUS_LOW;
_delay_us(5);
}
_delay_us(50);
}
BUS_HIGT;
_delay_us(15);
}
int reverse_CRC(uint8_t data_CRC)
{
uint8_t buff = data_CRC;
uint8_t CRC = 0;
for (uint8_t i = 7; i >= 0; i--)
{
CRC|=((buff>>i) & 0x01)<<(7-i);
}
return CRC;
}
int calculation_CRC8 (uint64_t seen_CRC1,uint8_t cvanto_byt) // вычисление CRC ID
{
uint64_t seen_CRC=seen_CRC1;
int DATA_REGISTR = 0;
uint8_t i = 0; // количество обработанных бит
while (i<=((8*cvanto_byt)+7))
{
if (DATA_REGISTR&(0x01 << 7))
{
DATA_REGISTR <<= 0x01;
DATA_REGISTR |=(seen_CRC&(1ULL<<i))>>i;
DATA_REGISTR ^= 0x131;
}
else
{
DATA_REGISTR <<= 0x01;
DATA_REGISTR |=(seen_CRC&(1ULL<<i))>>i;
}
i++;
}
return DATA_REGISTR;
}
int READ_MEMORY_ds18b20 (void)
{
MEMORY_ds18b20=0;
uint8_t CRC_MEMORY=0;
ds18b20_init();
write_ds18b20(SKIP_ROM);
write_ds18b20(READ_MEMORY);
BUS_HIGT;
_delay_us(15);
for(int i=0;i<=63;i++)
{
MEMORY_ds18b20|=(read_bit()<<i); // считываем побитово ID датчика
}
for(int i=0;i<=7;i++)
{
CRC_MEMORY|=(read_bit()<<i); // считываем побитово ID датчика
}
int CRC_calculate=calculation_CRC8 (MEMORY_ds18b20,8);
if( reverse_CRC(CRC_calculate)==CRC_MEMORY)
{
for(uint8_t i=0;i<=15;i++)
temperatura|=MEMORY_ds18b20&(1<<i);
}
int TEMP=(temperatura/16.0)*10;
char data_temperatura[5]={0};
sprintf(data_temperatura,"%d.%d",TEMP/10,TEMP%10);
print(data_temperatura);
return 0;
}
void WRITE_MEMORY_CONFIG_byte (void)
{
ds18b20_init();
write_ds18b20(SKIP_ROM);
write_ds18b20(WRITE_ROM);
write_ds18b20(0x4b); // Th=45 градусам
write_ds18b20(0x46); // Tl=45 градусам
write_ds18b20(0x7F); // 10 bit градусам
write_ds18b20(COPY_ROM);
}
void conversion_temperature(void)
{
ds18b20_init();
write_ds18b20(SKIP_ROM);
write_ds18b20(CONVERT_TEMPERATUR);
while(!(ds18b20_PIN&(1<<DQ))) { }
}
void read_ID (void)// чтение ID ds18b20
{
uint8_t CRC_ID=0;
ds18b20_init();
write_ds18b20(READ1_ROM);
BUS_HIGT;
_delay_us(15);
for(uint8_t i=0;i<=55;i++)
{
ID_ds18b20|=(read_bit()<<i); // считываем побитово ID датчика
}
for(uint8_t i=0;i<=7;i++)
{
CRC_ID|=(read_bit()<<i); // считываем побитово ID датчика
}
calculation_CRC8 (ID_ds18b20,7);
}
int main(void)
{
LCD_init();
WRITE_MEMORY_CONFIG_byte();
//read_ID();
while(1)
{
conversion_temperature();
READ_MEMORY_ds18b20();
}
}[uquote="da-nie",url="/forum/viewtopic.php?p=3551245#p3551245"]Советую скачать cppcheck[/uquote] хороший инструмент,необходимая вещь для новичка!отсканировал свой косячный код выдало несколько явных ошибок и одну сомнительную,все исправил и заработало. Спасибо большое,сегодня спать хоть буду спокойно
Re: Вопросы по С/С++ (СИ)
Столкнулся с проблемой. Хочу в устройстве сохранять настройки между включениями-выключениями. Микроконтроллер MSP432P401R. У него встроенного еепрома нет. Но я подумал, что мог бы использовать последние блоки флэш памяти с адреса 3f000 до 3ffff. Благо этого флэша там аж 256килобайт. Попробовал, сделал функцию записи во флэш после выхода из конфигурационного меню. Запустил. Запускаю отладчик, смотрю память: FFFFFFFFFFFFF. Выполняю под отладчиком - всё работает. Выхожу из отладчика, захожу по-новой - снова FFFFFFFFFFF. Короче при каждой перепрошивке вся память стирается. Можно ли как-то этот участок памяти "обезопасить" от стирания. Или хотя бы, чтобы при прошивке там записывались бы какие-то начальные установки.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."