Вопросы по С/С++ (СИ)
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Она меняется в другой подпрограмме, но я, когда встал в ступор, специально переде этой процедурой вписал i=0, но результат был тем же.
Тем не менее я проверил, 0 и 2 в другом месте назначаются.
Тем не менее я проверил, 0 и 2 в другом месте назначаются.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- Реклама
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
В другом месте - это не в прерывании ли, часом?
Если так, то такое поведение может быть результатом оптимизации кода компилятором.
Если так, то такое поведение может быть результатом оптимизации кода компилятором.
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не в прерывании. Но я же говорю, что прямо перед этой операцией назначаю, и безрезультатно.
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
а так что будет?
Код: Выделить всё
if ((row < 2) && ((digit == i) || (digit == (i + 1)))) val = 0x10;если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Да всё также и будет. У "+" всяко приоритет выше, чем у "==".ARV писал(а):а так что будет?Код: Выделить всё
if ((row < 2) && ((digit == i) || (digit == (i + 1)))) val = 0x10;
У человека явно проблемы с переменной i. Скорее всего, дело рук оптимизатора. Пусть, для начала, volatile заюзает для переменных.
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Это оптимизация. Отключил ее и проверка начала осуществляться, но при этом прилично вырос код. Я еще вечером игрался с volatile, но результатов никаких.
То, что предлагал ARV, я делал, но его пост напомнил мне о том, что я забыл упомянуть одну вещь: когда digit == i, это всегда исполняется (т.е. когда 0 == 0), но когда digit становится 1, сравнение i+1 обходится стороной.
Раньше это выражение стояло в прерывании и работало, но как только я перенес его в другое место, стало выкидывать такие вот коленца.
Сейчас еще поиграюсь.
P.S. Исследования показали, что в выражении digit == i + 1 компилятор упорно не желает видеть все, что после i. Скобки не помогают. менял местами слагаемые, задавал отдельную переменную , равную 1 и складывал с i. Даже делал (i | 1) в разных комбинациях. Оптимизатор принципиально игнорирует наращивание.
Уже злюсь, со вчерашнего вечера этой фигней маюсь.
P.P.S. РЕШЕНО правой рукой до носа через левое ухо, но хотя бы работает. Оптимизацию не трогал.
Исследования показали, что даже без volatile переменная i до этой операции доходит нормально (0 или 2 в нужные моменты), просто компилятор упорно не желал делать i+1. Кстати, это Кейл. Но я все равно обманул его
Всем микрорадиокотам спасибо за поддержку!
То, что предлагал ARV, я делал, но его пост напомнил мне о том, что я забыл упомянуть одну вещь: когда digit == i, это всегда исполняется (т.е. когда 0 == 0), но когда digit становится 1, сравнение i+1 обходится стороной.
Раньше это выражение стояло в прерывании и работало, но как только я перенес его в другое место, стало выкидывать такие вот коленца.
Сейчас еще поиграюсь.
P.S. Исследования показали, что в выражении digit == i + 1 компилятор упорно не желает видеть все, что после i. Скобки не помогают. менял местами слагаемые, задавал отдельную переменную , равную 1 и складывал с i. Даже делал (i | 1) в разных комбинациях. Оптимизатор принципиально игнорирует наращивание.
Уже злюсь, со вчерашнего вечера этой фигней маюсь.
P.P.S. РЕШЕНО правой рукой до носа через левое ухо, но хотя бы работает. Оптимизацию не трогал.
Исследования показали, что даже без volatile переменная i до этой операции доходит нормально (0 или 2 в нужные моменты), просто компилятор упорно не желал делать i+1. Кстати, это Кейл. Но я все равно обманул его
Код: Выделить всё
in = digit + i; // т.е. in будет равен 0-1 или 4-5.
if ((row < 2) && ((in < 2) || (in > 3))) val = 0x10;
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
Подскажите пожалуйста почему так происходит, контроллер ATmega8 gcc version 4.3.3
При таком коде занимает 88 байт флеша, если же раскоментировать строку со здвигом и закоментировать с делениями - 104 байта. Если объявить эту функцию как static, то при любом варианте 84 байта. Причем разница в размерах тем больше, чем чаще вызывается эта функция гдето в коде.
Код: Выделить всё
uint8_t bcd2bin(uint8_t value) {
return (value / 16) * 10 + (value % 16);
// return (value >> 4) * 10 + (value & 0x0F);
}
int main(void) {
uint8_t in, out;
in = PINB;
out = bcd2bin(in);
PORTC = out;
for(;;) {
}
}
«И всё-таки она вертится!»
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
во-первых, у вас 2 разных выражения, отсюда и разный объем при использовании одного и другого:Apparatchik писал(а):почему так происходит
во-вторых, если функция объявлена static и используется только в одном месте, она почти со 100% гарантией будет компилятором (оптимизатором) проинлайнена в коде. т.к. в этом случае нет накладных расходов на передачу параметров и возврат результата, это сокращает объем кода.Apparatchik писал(а): return (value / 16) * 10 + (value % 16);
// return (value >> 4) * 10 + (value & 0x0F);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
В другом компиляторе (для STM32) эти выражения дают одинаковый по размеру код, вот я и подумал что оптимизатор их должен привести к одному и тому же. Если она static ведь оптимизатор дает одинаковый размер.ARV писал(а):во-первых, у вас 2 разных выражения, отсюда и разный объем при использовании одного и другого:
«И всё-таки она вертится!»
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
неисповедимы пути оптимизатора... смените версию avr-gcc и наверняка сможете получить еще один вариант...Apparatchik писал(а):вот я и подумал что оптимизатор их должен привести к одному и тому же
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Таки да. У меня, например, что деление на 16, что сдвиг на 4 генерирует абсолютно одинаковый ассемблерный код. Причём сдвиг там даже не используется - вместо сдвига на 4 там просто swap байта:
Спойлер
Код: Выделить всё
uint8_t bcd2bin(uint8_t value)
{
return (value >> 4) * 10 + (value & 0x0F);
//return (value / 16) * 10 + (value % 16);
}
mov r25, r24
swap r25
andi r25, 0x0F ; 15
andi r24, 0x0F ; 15
ldi r18, 0x0A ; 10
mul r25, r18
add r24, r0
eor r1, r1
retRe: Вопросы по С/С++ (СИ)
А вы сохрание asm выхлоп компилятора для обеих вариантов и сравните в каком-нибудь двухпанельном diff-e - сразу покажет, что там оптимизатор не так понял. Попробуйте сравнить варианты с частями выражения - до '+' и после него.Apparatchik писал(а):При таком коде занимает 88 байт флеша, если же раскоментировать строку со здвигом и закоментировать с делениями - 104 байта.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Можно ли sizeof применять к одной из размерностей массива?
Re: Вопросы по С/С++ (СИ)
FeCat писал(а):Можно ли sizeof применять к одной из размерностей массива?
Код: Выделить всё
int aaa[2][3][4] = { 0 };
int z = sizeof(aaa);
int z1 = sizeof(aaa[0]);
int z2 = sizeof(aaa[0][0]);
int z3 = sizeof(aaa[0][0][0]);
_tprintf(_T("%d %d %d %d "), z, z1, z2, z3);
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Или, чуть доработав:
6 7 8
Код: Выделить всё
int aaa[6][7][8];
int z0 = sizeof(aaa);
int z1 = sizeof(aaa[0]);
int z2 = sizeof(aaa[0][0]);
int z3 = sizeof(aaa[0][0][0]);
printf("%d %d %d \n", z0/z1, z1/z2, z2/z3);Re: Вопросы по С/С++ (СИ)
[quote="WiseLord"]Или, чуть доработав:[/code]
Да, совершенству нет предела:
Код: Выделить всё
#ifndef _countof
#define _countof(__a) (sizeof(__a) / sizeof(*__a))
#ednif
_tprintf(_T("%d %d %d"), _countof(aaa), _countof(aaa[0]), _countof(aaa[0][0]));
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Огромное спасибо!
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Появился не совсем понятный мне момент.
Код:
Значение flash_adr приводится к указателю на тип (volatile uint16_t*), затем происходит доступ записи по этому адресу.
Я хочу понять как распутывается эта запись.
Допустим имеем
Что здесь происходит?
а) работа(инкремент) с указателем-переменной как с volatile
б) копирование данных по адресу ptr с отключенной оптимизацией компилятора.
Код:
Код: Выделить всё
#define __IO volatile /*!< Defines 'read / write' permissions
__INLINE void FlashWord16Prog(uint32_t flash_addr, uint16_t data)
{
...
/* (2) Perform the data write (half-word) at the desired address */
*(__IO uint16_t*)(flash_addr) = data; /* (2) */
...
}Я хочу понять как распутывается эта запись.
Допустим имеем
Код: Выделить всё
volatile uint16_t *ptr;
*ptr = data;
ptr++;а) работа(инкремент) с указателем-переменной как с volatile
б) копирование данных по адресу ptr с отключенной оптимизацией компилятора.
Re: Вопросы по С/С++ (СИ)
Ничего сложного. Значение data копируется в 16-битную ячейку памяти, на которую указывает ptr. Затем, инкремент смещает указатель так чтобы он указывал на следующую 16-битную ячейку. Ключевое слово volatile гарантирует, что запись в ячейку произойдет именно в этом месте (это так, по простому).uk8amk писал(а):Что здесь происходит?


