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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

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

Сообщение unalex »

vitalik_1984 писал(а):по мне так вот это вообще лишнее


задача была помигать светодиодами, если вы считаете что в данной ситуации несколько тиков процессора важнее универсальности, то

vitalik_1984 писал(а):просто вспоминается мысль о говнокоде


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

ЗЫ. для справки - задачи бывают разные, в одной важен размер кода, в другой скорость, так что делать выводы о том использовать свитч или отдельные функции, можно только ознакомившись с конкретным ТЗ
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Подскажите, что я делаю не так.....
Пытаюсь сравнить 2 значения в памяти, на второе из них уже указывает указатель, делаю так:

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

if (*pIrNecData == *(--pIrNecData))
    {.....} 

Компилятор почемуто начисто вырезает сравнение.....
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

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

Сообщение unalex »

shads писал(а):Компилятор почемуто начисто вырезает сравнение.....


это называется оптимизация
зачем их сравнивать, если изначално понятно, что они указывают на одинаковые/разные объекты?
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

shads писал(а):Компилятор почемуто начисто вырезает сравнение.....

Или что-то объявить как volatile... или объявить дополнительную переменную как volatile и часть преобразований вести через неё...
"Я не даю готовых решений, я заставляю думать!"(С)
Совесть
Встал на лапы
Сообщения: 106
Зарегистрирован: Пн мар 26, 2012 05:25:06

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

Сообщение Совесть »

Один нашел в этой строчке "одинаковые/разные объекты". Второй не разбираясь лепит "volatile". Браво!!! :)))
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

А третий - только б звездануть... :)))
Давай... присоединяйся к своим братьям-говнокодерам... портянкой на два листа одним светодиодом рулить будешь... :)))
"Я не даю готовых решений, я заставляю думать!"(С)
Совесть
Встал на лапы
Сообщения: 106
Зарегистрирован: Пн мар 26, 2012 05:25:06

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

Сообщение Совесть »

Ога, и еще писать переносимый код, хаить CV и восхвалять ассемблер. Вроде ничего не забыл из основных тем форума?!
А по делу, желания нет гадать в чем проблема, смотря на одну строчку кода.
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

shads писал(а):Пытаюсь сравнить 2 значения в памяти, на второе из них уже указывает указатель, делаю так:
приведите листинг. компилятор оптимизирует в целом, а не отдельно строчку. Видимых замечаний по этому коду нет.
Ставим плюсы: )
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Да хоть листинг, хоть строчку..... как я понял компилятор (пользуюсь AVRStudio4) в подобных случаях чего то не понимает..... толи нескольких указателей в сравнении, толи префиксы ++/-- к указателям, толи еще чего.....
Вот простенький пример (свой код не стал показывать, т.к. сложнее разобраться будет)

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

#include <avr/io.h>
char massiv [10];

int main (void)
{
    char* pMassiv = massiv;
    for (char i=0; i<10; i++)
        *pMassiv++ = i;

    if (*(--pMassiv) == *(--pMassiv))
        PORTB = 0xff;
    else
        PORTB 
= 0x00;

    while (1){}
}
 

Сравниваем последние 2 элемента массива, и хотя там у нас разные данные, компиль просто (молча) вырезает сравнение, и выполняет действие PORTB = 0xff, как будто у нас положительный результат сравнения.....

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

6:        {
+
00000024:   E6E0        LDI       R30,0x60       Load immediate
+00000025:   E0F0        LDI       R31,0x00       Load immediate
+00000026:   E080        LDI       R24,0x00       Load immediate
10
:               *pMassiv++ = i;
+
00000027:   9381        ST        Z+,R24         Store indirect and postincrement
9
:            for (char i=0; i<10; i++)
+
00000028:   5F8F        SUBI      R24,0xFF       Subtract immediate
+00000029:   308A        CPI       R24,0x0A       Compare with immediate
+0000002A:   F7E1        BRNE      PC-0x03        Branch if not equal
13
:               PORTB = 0xff;
+
0000002B:   EF8F        SER       R24            Set Register
+0000002C:   BB88        OUT       0x18,R24       Out to I/O location
+0000002D:   CFFF        RJMP      PC-0x0000      Relative jump
13
:               PORTB = 0xff;
+
0000002E:   94F8        CLI                      Global Interrupt Disable
+0000002F:   CFFF        RJMP      PC-0x0000      Relative jump
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

А вот так, работает.....
Но уперто не хочет применять индексный регистр, хотя казалось бы - адрес в нем уже имеется..... так нет же тратит лишний флэш на загрузку обоих байтов командой LDS.....

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

#include <avr/io.h>
char massiv [10];

int main (void)
{
    char* pMassiv = massiv;
    for (char i=0; i<10; i++)
        *pMassiv++ = i;

    char temp = *(--pMassiv);
    if (temp == *(--pMassiv))
        PORTB = 0xff;
    else
        PORTB 
= 0x00;

    while (1){}
}
 
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

у Вас же другой вопрос был. без двух преддекрементов в одной строчке.
Ставим плюсы: )
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

ibiza11 писал(а):у Вас же другой вопрос был. без двух преддекрементов в одной строчке.

Это ничего не меняет.....

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

#include <avr/io.h>
char massiv [10];

int main (void)
{
    
charpMassiv massiv;
    for (
char i=0i<10i++)
        *
pMassiv++ = i;

    
pMassiv massiv;
    if (*
pMassiv == *(++pMassiv))
        
PORTB 0xff;
    else
        
PORTB 0x00;

    while (
1){}

результат:

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

5:        {
+
00000024:   E6E0        LDI       R30,0x60       Load immediate
+00000025:   E0F0        LDI       R31,0x00       Load immediate
+00000026:   E080        LDI       R24,0x00       Load immediate
8
:                *pMassiv++ = i;
+
00000027:   9381        ST        Z+,R24         Store indirect and postincrement
7
:            for (char i=0i<10i++)
+
00000028:   5F8F        SUBI      R24,0xFF       Subtract immediate
+00000029:   308A        CPI       R24,0x0A       Compare with immediate
+0000002A:   F7E1        BRNE      PC-0x03        Branch if not equal
12
:               PORTB 0xff;
+
0000002B:   EF8F        SER       R24            Set Register
+0000002C:   BB88        OUT       0x18,R24       Out to I/O location
+0000002D:   CFFF        RJMP      PC-0x0000      Relative jump
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

в общем, поскольку в условии if используется одна переменная (указатель) и в составе условия есть математические операции пред/пост декремента/инкремента, то они выполняются до проверки условия.
т.е в случае

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

if (*pIrNecData == *(--pIrNecData))
    {.....} 
сначала происходит преддекремент pIrNecData, а потом уже сравнение двух выражений *(pIrNecData), которые равны.
Аналогично во всех остальных случаях.
Ставим плюсы: )
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Корочь химера был прав
HHIMERA писал(а):объявить дополнительную переменную как volatile и часть преобразований вести через неё...
Тока можно и без volatile.

ЗЫ Просто у программиста логика - человеческая, а у компа - машинная.....

ЗЫЗЫ В общем вывод: нельзя в сравнении использовать один указатель больше одного раза..... правильный вывод?

ЗЫЗЫЗЫ Интересно, а почему тогда компилятор ни гугу.... хотябы ругнулся на лишний (недостающий) префикс. Ведь с человеческой точки зрения, все должно произойти именно так как я изначально ожидал..... Наверное упущение программеров создавших компилятор.
Надо еще в 6-ке проверить, как себя вести будет такое построение.....
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

shads писал(а):ЗЫЗЫ В общем вывод: нельзя в сравнении использовать один указатель больше одного раза..... правильный вывод?
Неправильный вывод
вот пример, который будет работать:

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

if (*pIrNecData == *(pIrNecData-1))
    {.....}  

Надо еще в 6-ке проверить, как себя вести будет такое построение.....
Можете не проверять, я проверял в Keil MDK ARM - компилятор интерпретирует Вашу запись аналогично 4ой студии.
Последний раз редактировалось ibiza11 Вт мар 19, 2013 13:30:08, всего редактировалось 1 раз.
Ставим плюсы: )
Аватара пользователя
IM1
Грызет канифоль
Сообщения: 268
Зарегистрирован: Вт фев 16, 2010 12:10:38
Откуда: Воронеж, Россия

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

Сообщение IM1 »

shads писал(а):Корочь химера был прав
Ага.

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

#include <avr/io.h>

char massiv [10];
volatile char *pMassiv = massiv;
int main (void)
{
   for (char i=0; i<10; i++)
   *pMassiv++ = i;
   if (*(--pMassiv) == *(--pMassiv))
   PORTB = 0xff;
   else
   PORTB = 0x00;

while (1){}

Дизассемблер

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

{
   for (char i=0; i<10; i++)
00000024  LDI R24,0x00      Load immediate
   *pMassiv++ = i;
00000025  LDS R30,0x0060      Load direct from data space
00000027  LDS R31,0x0061      Load direct from data space
00000029  MOVW R26,R30      Copy register pair
0000002A  ST X+,R24      Store indirect and postincrement
0000002B  STS 0x0061,R27      Store direct to data space
0000002D  STS 0x0060,R26      Store direct to data space
   for (char i=0; i<10; i++)
0000002F  SUBI R24,0xFF      Subtract immediate
00000030  CPI R24,0x0A      Compare with immediate
00000031  BRNE PC-0x0C      Branch if not equal
   if (*(--pMassiv) == *(--pMassiv))
00000032  STS 0x0061,R31      Store direct to data space
00000034  STS 0x0060,R30      Store direct to data space
00000036  LDD R25,Z+0      Load indirect with displacement
00000037  SBIW R30,0x01      Subtract immediate from word
00000038  STS 0x0061,R31      Store direct to data space
0000003A  STS 0x0060,R30      Store direct to data space
0000003C  LDD R24,Z+0      Load indirect with displacement
0000003D  CP R25,R24      Compare
0000003E  BRNE PC+0x04      Branch if not equal
   PORTB = 0xff;
0000003F  SER R24      Set Register
00000040  OUT 0x18,R24      Out to I/O location
00000041  RJMP PC+0x0002      Relative jump
   PORTB = 0x00;
00000042  OUT 0x18,R1      Out to I/O location
00000043  RJMP PC-0x0000      Relative jump
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

:evil: бред! зачем объявлять указатель на массив volatile? он что, у Вас в прерывании меняется?
естественно volatile будет работать в этом случае, поскольку при каждом обращении к указателю будет производиться его преддекремент. Но это равносильно отключению оптимизации этого указателя. Так делать нельзя.
Ставим плюсы: )
Аватара пользователя
IM1
Грызет канифоль
Сообщения: 268
Зарегистрирован: Вт фев 16, 2010 12:10:38
Откуда: Воронеж, Россия

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

Сообщение IM1 »

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

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

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

Так делать нельзя.
Ну почему же нельзя. volatile как раз и нужен для того, что бы сказать компилятору, что он "не прав" и не должен оптимизировать мысли программиста.
По поводу инкремента. В строке используется же пред-, а не пост-инкремент. Если бы был постинкремент, то оптимизатор можно было бы понять, т.к. условие будет всегда = true. Вообще не понятно, почему он обрезает эту строку, хотя бы инкремент оставил бы.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Аlex писал(а):По поводу инкремента. В строке используется же пред-, а не пост-инкремент. Если бы был постинкремент, то оптимизатор можно было бы понять, т.к. условие будет всегда = true. Вообще не понятно, почему он обрезает эту строку, хотя бы инкремент оставил бы.
Компилятор это делает потому, что дальше эта переменная нигде не используется. Поставьте вывод её значения в какой-либо порт и компилятор сделает инкремент.

Думаю, что многие будут удивлены результатами этих строк (например для a=5).
x = (++a) + (++a);
x = (a++) + (a++);
Однако всё строго по стандарту.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

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