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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

[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]так и должно быть
AAX
Опытный кот
Сообщения: 718
Зарегистрирован: Сб ноя 16, 2013 23:34:34

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

Сообщение AAX »

[uquote="ARV",url="/forum/viewtopic.php?p=3544835#p3544835"]планирую инициализировать все поля структуры y одинаковой строкой[/uquote]планировать мало, нужно сделать :) Ваш код инициализирует только первый элемент. Наверное, Вы по аналогии с

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

my_t var = {0};
решили, что всё проинициализируется "1"?
"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: Вопросы по С/С++ (СИ)

Сообщение ARV »

AAX писал(а):решили, что всё проинициализируется "1"?
да, а разве я не прав? ведь

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

int arr[100] = {7};
struct var { int a; int b; int c} = {7};
проинициализирует все элементы и поля семерками... или нет? для структур правило "для всех" не действует?
AAX писал(а): Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
у меня по умолчанию -Wall
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

ARV писал(а):для структур правило "для всех" не действует?
Нет, конечно. С чего бы ?
Проинициализируется только первое поле структуры.
Такое правило (инициализация всех ячеек одним значением) только для массивов. В структурах могут быть разные типы полей, по этому подобное правило было бы нелогичным.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

ARV писал(а):проинициализирует все элементы и поля семерками... или нет?
ЕМНИП, и для массива - нет. Только первый элемент, остальные - нулями.
Для GCC можно ещё '...' использовать для указания диапазона.
В любом случае, любые попытки инициализировать элементы чем-то, отличным от нуля, будут увеличивать размер прошивки, тем больше, чем больше элементов в массиве, структуре и т.д.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Аlex писал(а):Такое правило (инициализация всех ячеек одним значением) только для массивов
мда... как обманчива природа... спасибо за науку.
WiseLord писал(а):В любом случае, любые попытки инициализировать элементы чем-то, отличным от нуля, будут увеличивать размер прошивки
в моём случе речь об инициализации EEPROM, так что ничего увеличиваться не будет.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
OKF
Это не хвост, это антенна
Сообщения: 1388
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3545811#p3545811"]ЕМНИП, и для массива - нет. Только первый элемент, остальные - нулями.[/uquote]
Неохота искать источники, но я так тоже всегда считал. А значит откуда то вбилось.)
AAX
Опытный кот
Сообщения: 718
Зарегистрирован: Сб ноя 16, 2013 23:34:34

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

Сообщение AAX »

[uquote="ARV",url="/forum/viewtopic.php?p=3545804#p3545804"]
AAX писал(а):решили, что всё проинициализируется "1"?
да, а разве я не прав?[/uquote]я ж ссылку дал. Можно было бы за минуту прочесть, и понять, прав-не прав... Это ж не википедия :) Это руководство GCC.
[uquote="ARV",url="/forum/viewtopic.php?p=3545804#p3545804"]
AAX писал(а): Но чтобы получить это предупреждение мне пришлось добавить gcc опцию -Wmissing-braces
у меня по умолчанию -Wall[/uquote]Вы, наверное, решили, что опция -Wall включает все возможные предупреждения компилятора? This enables all the warnings about constructions that some users consider questionable. Впрочем, ходить по ссылкам, читать - скукота... гораздо лучше положиться на мнение неизвестного человека из интернетов, с вероятностью 95% - бестолкового, т.к. "толковым" в интернетах отвисать некогда ;) Мкей, тогда давайте так: -Wall не включает всех возможных предупреждений. С настройками по-умолчанию (-Wall) приведённая Вами конструкция не вызывает появления каких-либо предупреждений при компиляции при помощи gcc version 5.4.0 (AVR_8_bit_GNU_Toolchain_3.6.0_1734)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

AAX писал(а):Это руководство GCC
всегда перед тем, как задать вопрос на форуме, пытаюсь найти ответ в доступных мне источниках, в частности, при помощи поиска в google
AAX писал(а):приведённая Вами конструкция не вызывает появления каких-либо предупреждений при компиляции при помощи gcc version 5.4.0
в том-то и дело, что от версии к версии avr-gcc меняет своё поведение "по умолчанию". в документации тоже не всегда легко найти особенности именно этой версии. но главное - невозможно понять, почему именно так, а не иначе "было-стало". и в этом случае обращаюсь на форум.
AAX писал(а):гораздо лучше положиться на мнение неизвестного человека из интернетов, с вероятностью 95% - бестолкового
вы сейчас себя имели ввиду? ;)

указанные мной версии компилятора выдают указанные мною предупреждения, и ведут себя так, как я описал. хоть я и имею набор версий от 3.х.х. до 8.х.х, проверять каждую как-то лень. причина "странной" на мой взгляд инициализации структур мне уже стала понятна - спасибо "бестолковым", кто уже успел мне объяснить. причина появления варнингов - не понятна до сих пор, как не понятен до сих пор и способ избавления от них (не считая отключения опции) без необходимости инициализировать каждое поле принудительно.

пока это всё.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

[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.
AAX
Опытный кот
Сообщения: 718
Зарегистрирован: Сб ноя 16, 2013 23:34:34

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

Сообщение AAX »

[uquote="ARV",url="/forum/viewtopic.php?p=3549882#p3549882"]вы сейчас себя имели ввиду? ;)[/uquote]в том числе и себя, конечно.
Если человек высказывает мнение по обсуждаемому вопросу, обычно следует поинтересоваться источником его знания. И ознакомиться с ним, т.к. 1) люди не всегда формулируют точно, мануалы и учебники пишут лучше. Ну, и просто - при каждом пересказе информации свойственно искажаться. 2) человек, обычно, высказывается только о предмете, вызвавшем обсуждение. В мануале или в учебнике есть шанс получить дополнительное полезное знание, о вещах, не упомянутых в контексте данного обсуждения.
Даже если Вам повезло, и Вы встретились (чудом) в интернетах с "толковым" человеком, у него наверняка не будет времени вникать в нюансы Вашего вопроса и разжёвывать ответ. Это как у линуксоидов когда-то было принято: вместо ответа на вопрос отправлять читать нужный man.
Аватара пользователя
shindax
Потрогал лапой паяльник
Сообщения: 378
Зарегистрирован: Сб сен 19, 2009 07:02:19

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

Сообщение shindax »

[uquote="WiseLord",url="/forum/viewtopic.php?p=3545811#p3545811"]...
Только первый элемент, остальные - нулями....[/uquote]
В данном случае только первый элемент. Заполнять остальное нулями компилятор не обязан. Чистка буфера до обмена в Си всегда отдавалась на откуп программисту. И это правильно.
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

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

А вот интересно, если написать 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
OKF
Это не хвост, это антенна
Сообщения: 1388
Зарегистрирован: Вт июн 07, 2011 08:03:18

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

Сообщение OKF »

А неинициализированные глобальные переменные (в т.ч. и массивы) разве не обнуляются компилятором, стартап секцией?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Статические точно обнуляются, а глобальные, как отметил shindax, в принципе, не обязательно, но практически наверняка, компилятор их оптимизирует подобно статическим. По крайней мере, в случае avr-gcc и типичных флагах компиляции (-Os) разницы между прошивками, где глобальные массивы объявлены как static, и прошивками, где - не static, никакой нет.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

здравствуйте! проблема с кодом, выложить пока не могу, т. к. не рядом с компом. но и не могу успокоиться найдя проблему.суть вот в чем:в целом код работал, после незначительных, на мой взгляд, манипуляции с переменными он перестал выполнять свои функции. пытался отладчиком отловить баг, но не смог. компилируется чисто, при отладке в дис. коде вижу что происходит сброс PC(rjump PC 0*0000) . Подскажите пожалуйста, почему эта гадость могла возникнуть, где копать?
Аватара пользователя
da-nie
Говорящий с текстолитом
Сообщения: 1590
Зарегистрирован: Вс июн 24, 2012 16:07:00
Откуда: Лен.Обл.
Контактная информация:

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

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

Варианты, когда код перестаёт работать после незначительного изменения:
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
Аватара пользователя
ROMan2947
Грызет канифоль
Сообщения: 287
Зарегистрирован: Сб янв 23, 2016 00:59:59
Откуда: Чебоксары

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

Сообщение ROMan2947 »

[uquote="da-nie",url="/forum/viewtopic.php?p=3551245#p3551245"]Варианты, когда код перестаёт работать после незначительного изменения[/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();
   
}

}
Добавлено after 1 hour 3 minutes 21 second:
[uquote="da-nie",url="/forum/viewtopic.php?p=3551245#p3551245"]Советую скачать cppcheck[/uquote] хороший инструмент,необходимая вещь для новичка!отсканировал свой косячный код выдало несколько явных ошибок и одну сомнительную,все исправил и заработало. Спасибо большое,сегодня спать хоть буду спокойно :beer:
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Столкнулся с проблемой. Хочу в устройстве сохранять настройки между включениями-выключениями. Микроконтроллер MSP432P401R. У него встроенного еепрома нет. Но я подумал, что мог бы использовать последние блоки флэш памяти с адреса 3f000 до 3ffff. Благо этого флэша там аж 256килобайт. Попробовал, сделал функцию записи во флэш после выхода из конфигурационного меню. Запустил. Запускаю отладчик, смотрю память: FFFFFFFFFFFFF. Выполняю под отладчиком - всё работает. Выхожу из отладчика, захожу по-новой - снова FFFFFFFFFFF. Короче при каждой перепрошивке вся память стирается. Можно ли как-то этот участок памяти "обезопасить" от стирания. Или хотя бы, чтобы при прошивке там записывались бы какие-то начальные установки.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Ответить

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