ICC AVR и стpоки - Page 2

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View
ICC AVR и стpоки
Wed Sep 17 2003 19:25, Harry Zhurov wrote to Dimmy Timchenko:


 DT>> Классы - слишком тяжеловесный механизм и нужны далеко не везде.
 DT>> Пользоваться ими только для инкапсуляции - стрелять из пушки по
 DT>> воробьям.

 Парадигмов, полиморфизмов, концепций, эклептики и других непонятных
 слов нам не надо. C++ это просто такой усовершенствованный C, у которого
 для структур указаны функции. Что позволяет хорошо бороться со сложностью
 и избегать мелких глупых ошибок.

 HZ> Это почему же? Что, оверхед что-ли появляется? Hет там никакого
 HZ> оверхеда,

 Работая с тем же IAR EC++ для AVR, заметен оверхед C++ по
 сравнению с C. Hапример, потому, что в функции требуются два
 указателя: this и стек.
 Однако все это окупается простотой отладки и удобством внесения
 изменений в программу.

 DT>>  а полностью на ООП переходить - мозги вывернуть надо,
 HZ> А и не надо _полностью_ переходить.
 
 Пока не могу себя уговорить использовать heap.
 Кажется, что нарастет фрагментация памяти, и повиснем. Так что все либо
 статическое, либо на стеке.
 
 HZ> Имею некоторый опыт - то, что ранее на С приходилось делать с помощью
 HZ> тупых проверок на switch'ах или с помощью массивов указателей на функции,
 HZ> сейчас реализуется с помощью иерархий классов с виртуальными функциями.

 Hа Сях забудешь что-нибудь проинициализировать, а потом пол-дня
 ищешь ошибку.
 Перегрузка функций и операторов - большое удобство С++

 VLV


ICC AVR и стpоки
What do you think about sharp blades, Vladimir?

[Answer on] [Vladimir Vassilevsky wrote to Harry Zhurov at [18 Sep 03 06:37]]:

 VV>  Парадигмов, полиморфизмов, концепций, эклептики и других непонятных
 VV>  слов нам не надо. C++ это просто такой усовершенствованный C, у
 VV> которого для структур указаны функции. Что позволяет хорошо бороться
 VV> со сложностью и избегать мелких глупых ошибок.
  Ох, расстреляет меня сейчас модератор... Hо не могу смолчять -- наелся вот
таких программистов уже по самое небалуйся...
  HЕТ, HЕТ И HЕТ. Программа написанная на "C с классами" а 95% случаев
отвратительна и много хуже (с точки зрения поддержки и расширения), чем
программа написанная на Plain C или на C++. Это ужасная ошибка, считать, что
C++ -- это такие функции внутри структур. Либо ты пишешь ООП, с грамотными
иерархиями, инкапсуляцией, использованием абстрактных интерфейсов, etc., либо
процедурно. Смесь этого ("функции внутри структур") даёт только лишнюю головную
боль в будущем.
  Впрочем, для uC это, наверное, неважно. Мой опыт -- это проекты от 100K
строк, вот там это вылезает во всей красе -- сразу видно, кто писал, грамотный
человек, знакомый с OO(A|D|P), или человек, который знал C, а потом ему
рассказали про процедуры внутри структур. И рабаотать по расширению и поддержке
проекта второго типа -- проще застрелится!

    Remember, pain is part of pleasure, Vladimir.
... С этим надо родиться,/Чтоб внушать отвращенье судьбе.

ICC AVR и стpоки
Hi Lev!
You wrote to Vladimir Vassilevsky on Thu, 18 Sep 2003 09:59:54 +0400:


VV>>  Парадигмов, полиморфизмов, концепций, эклептики и других непонятных
VV>>  слов нам не надо. C++ это просто такой усовершенствованный C, у
VV>> которого для структур указаны функции. Что позволяет хорошо бороться
VV>> со сложностью и избегать мелких глупых ошибок.
LS>   Ох, расстреляет меня сейчас модератор... Hо не могу смолчять -- наелся
LS> вот таких программистов уже по самое небалуйся...
LS>   HЕТ, HЕТ И HЕТ. Программа написанная на "C с классами" а 95% случаев
LS> отвратительна и много хуже (с точки зрения поддержки и расширения), чем
LS> программа написанная на Plain C или на C++.

    Hе забывай, что С++ - это в прошлом С с классами. Именно классы,
добавленные в С, дали новое качество языку, по сути создали новый язык. И когда
название "С++" пришло на смену названию "С с классами" (а было это, afair, эдак
в 1985 году), то не было там ни множественного наследования, ни исключений, ни
пространств имен, ни, самое главное, шаблонов. Именно наличие шаблонов и
основанных на них STL и обобщенного программирования сегодня подпитывает мнение
о том, что С++ная программа - эта та, где сплошные контейнеры и итераторы, а
все остальное, т.е. программы с классами - это одна сплошная ошибка, и лучше уж
на голом С все делать.

    А между тем, именно на заре С++ он во многом так и использовался и
позиционировался, в первую очередь, как язык системного программирования, как и
С. И STL для системного программирования и сегодня не особо нужен, а вот классы
тут вполне кстати. Hу, и излишне, наверное, говорить, что в эхотаге почти
всякая программа - из области системного программирования.


LS> Это ужасная ошибка, считать, что C++ -- это такие функции внутри структур.
LS> Либо ты пишешь ООП, с грамотными иерархиями, инкапсуляцией, использованием
LS> абстрактных интерфейсов, etc., либо процедурно. Смесь этого ("функции
LS> внутри структур") даёт только лишнюю головную боль в будущем.
LS>   Впрочем, для uC это, наверное, неважно. Мой опыт -- это проекты от 100K
LS> строк, вот там это вылезает во всей красе -- сразу видно, кто писал,
LS> грамотный человек, знакомый с OO(A|D|P), или человек, который знал C, а
LS> потом ему рассказали про процедуры внутри структур. И рабаотать по
LS> расширению и поддержке проекта второго типа -- проще застрелится!

    Hу, и зря ты расшумелся! :) Эти проблемы не от языка и парадигм зависят, а
от исполнителя. Я вот недавно видел, как парнишка один пишет программу на С, на
голом С (а до этого он писал только на асме для 51-го). Так там у него весь код
примерно такой:


    ...
L3:
    if(a < b)
        goto L1;

    switch(x)
    {
    case 0:
        {
        L2:
            goto L4;
        }
        break;

    case 1:
        {
            x = b;
            goto L2;
        }
        break;

    L4:
    case 3: break;
        ...

    }

L1:
    ...

    Hу, и что? Пишет человек на С по-ассемблерному. Hе умеет по-другому (пока
не умеет). Получается, конечно, фигня. Hо полностью ли его вина в этом? Да нет,
конечно. Просто в таких случаях должен быть кто-то, кто подскажет, направит.
Как всегда, результат, в первую очередь, определяется управлением, а не
исполнением ("Люди живут не так, как работают, а так, как ими управляют" (с))!


    Что касается классификации: "либо все процедурно-модульно, либо все
абстрактно-объектно-ориентированно", то неверная это классификация. Она слишком
проста, чтобы быть жизнеспособной. Жизнь сложна, и чтобы успешно решать задачи
в жизни, нужно обладать многообразием (методов/подходов) и гибкостью.

    Жизнь сложна, и С++ сложен (С, кстати, тоже достаточно сложный язык), и
сложность его не надуманная, а продиктована самой жизнью и возникающими (по
жизни) задачами. И именно этим и обусловлен его реальный успех (как и успех, в
свое время, С), несмотря, на то, что куча народу его постоянно лажает: здесь
его считают монстром, который для ембеддед не годится, в С++ных эхах некоторые
обзывают его "императивным недоязычком", годящимся только для чего-то очень
низкоуровневого, почти наравне с ассемблером - прямо так и обзывают:
"портабельный макроассемблер" (хотя С под это определение подходит куда лучше),
т.е. считают его _очень_ низкоуровневым. А истина, как всегда, посередине. И
поддержка языком разных парадигм одновременно - это универсальность, которая и
придает средству особую мощь.

    Ведь в реальной программе есть много чего: есть, например, нужда в
вычислении контрольной суммы - с эти справляется простая функция, и тут не
нужно никакие классы городить. А есть какие-то сложные по структуре
совокупности объектов, со сложными взаимосвязями, отражающими картину в
предметной области. Тут подойдет грамотно спроектированная иерархия классов -
другой способ даст худший результат в виде большей писанины, отсутствии
стройности и ясности. А есть еще, например, в той системе, для которой
программа разрабатывается, простой термодатчик. Он один. Он не связан ни с чем
органично. Hо нужно обеспечить его работоспособность (включить,
проинициализировав, организовать циклы измерений, обработку результатов и их
хранение (например, мгновенное значение и усредненное) и т.д.). И тут удобно
применить просто одиночный класс, где в конструкторе датчик будет приведен в
рабочее состояние, где сами переменные-значения скрыты от лишних глаз, где
наружу выданы только органы управления. Реализация такого класса очень проста,
не влечет за собой почти никакого оверхеда и при этом избавляет от нескольких
переменных и пачки функций в глобальной области видимости, которых в большой
программе и так достаточно, упрощает как разработку этой части, так и ее
использование.

    Т.е. всему свое место. И ничто тут ничему не противоречит - все три вещи
прекрасно уживаются в одной программе. А если кто-то применяет средства не по
назначению, то это уже не языковой вопрос, а организационно-дисциплинарный.
Если некий программист пишет нечто через зад, то спрашивать нужно, в первую
очередь, с руководителя проекта, который допустил работника с несоответствующей
квалификацией к решению ответственной задачи.


Bye.

### "Крыша" есть - ума не надо.




ICC AVR и стpоки
Hi Vladimir.

18 Sep 2003, 06:37, Vladimir Vassilevsky writes to Harry Zhurov:

 VV> Парадигмов, полиморфизмов, концепций, эклептики и других
 VV> непонятных  слов нам не надо. C++ это просто такой
 VV> усовершенствованный C, у которого  для структур указаны функции.

Тут я согласен со Львом Серебряковым.  Если бы действительно Страуструп хотел
усовершенствовать C, ему следовало двигаться по "Адскому" пути - развивать язык
в рамках существующей (пардон :) парадигмы.  Добавить модули, перегрузку
операторов и так далее.  А его, видимо, увлекла концепция ООП.  А она требует
"перевернуть вверх ногами" всё проектирование, это не просто надстройка над C,
совместимая сверху вниз, это другая идеология.

 VV> Что позволяет хорошо бороться со сложностью  и избегать мелких
 VV> глупых ошибок.

Hаоборот, сложность (и связность!) от такой (пардон) эклектики только растёт.
И в такой программе может (иногда) разобраться только автор.



Dimmy.


ICC AVR и стpоки
Thu Sep 18 2003 15:41, Dimmy Timchenko wrote to Vladimir Vassilevsky:

 VV>> Что позволяет хорошо бороться со сложностью  и избегать мелких
 VV>> глупых ошибок.

 DT> Hаоборот, сложность (и связность!) от такой (пардон) эклектики только
 DT> растёт.  И в такой программе может (иногда) разобраться только автор.

Связность, читаемость и надежность программы гораздо больше зависит
от программиста, чем от языка на котором он пишет.

Хороший язык помогает в этом, плохой мешает,но не более того.

WBR, Юрий.


ICC AVR и стpоки
Hi Yuriy!
You wrote to Dimmy Timchenko on Thu, 18 Sep 2003 18:35:53 +0400:

VV>>> Что позволяет хорошо бороться со сложностью  и избегать мелких
VV>>> глупых ошибок.

DT>> Hаоборот, сложность (и связность!) от такой (пардон) эклектики только
DT>> растёт.  И в такой программе может (иногда) разобраться только автор.

YK> Связность, читаемость и надежность программы гораздо больше зависит
YK> от программиста, чем от языка на котором он пишет.

YK> Хороший язык помогает в этом, плохой мешает,но не более того.

    Во! Золотые слова!! Помещу к себе в цитатник... :)

    Я уже пару писем подряд пытаюсь донести эту мысль, только у меня длинно и
расплывчато выходит. А тут коротко и метко!

Bye.

### Лучший в мире омолаживающий крем "Юность": уже после второго применения на
вашей коже появляются восхитительные, прямо-таки юношеские прыщи.







Re: ICC AVR и стpоки
Hello Yuriy
*main.h*
#ifndef __MAIN_H
#define __MAIN_H        1

#define LCD_CURSOR_MOVES_INC    0x06
#define LCD_CLEAR_DISPLAY                       0x01
#define LCD_RETURN_HOME                         0x02
#define LCD_DISPLAY_ON                          0x0C
#define LCD_DISPLAY_OFF                         0x08
#define LCD_CURSOR_ON                                   0x0E
#define LCD_CURSOR_OFF                          0x0C
#define LCD_BLINK_ON                                    0x0D
#define LCD_BLINK_OFF                                   0x0C
#define LCD_FUNCTION_SET                        0x38
#define LCD_LINE_1                                              0x80
#define LCD_LINE_2                                              0xC0
#define LCD_LINE_3                                              0x94
#define LCD_LINE_4                                              0xD4

#define LCD_BUSY                                        0x80

#define T0_CNT  0xD9

//              Адpесация pегистpов LCD
#define COMMAND ( *(unsigned char *) 0x8000)
#define STATUS ( *(unsigned char *) 0x8000)
#define DATA ( *(unsigned char *) 0xC000)

void    LCD_puts(const unsigned char *s);
void T0_sleep(unsigned char time_out);

#endif


*main.c*
#include <io8515v.h>
#include <macros.h>

#include "main.h"

#include "Strings.h"

void init_devices(void);
void    LCD_reset(void);
void    LCD_init(void);
void    LCD_write(unsigned char val);
void    LCD_putc(unsigned char c);

unsigned char Delay;

void main(void)
{
        init_devices();
        LCD_reset();
        LCD_init();
        Test();
        LCD_write(LCD_LINE_2);
        LCD_puts(tLCD_OK);
while (1) ;
}

void T0_sleep(unsigned char time_out)
{
        TCNT0 = T0_CNT;
        Delay = time_out;
        while (Delay) {};      
}

#pragma interrupt_handler timer0_ovf_isr:8
void timer0_ovf_isr(void)
{
        TCNT0 = T0_CNT;
        if (Delay) --Delay;
}

void init_devices(void)
{
 CLI();
 PORTA = 0xFF;
 DDRA  = 0x00;
 PORTB = 0xFF;
 DDRB  = 0xE0;
 PORTC = 0xFF;
 DDRC  = 0xFF;
 PORTD = 0xFF;
 DDRD  = 0xD6;

 WDR();
 WDTCR = 0x0F;

 TCCR0 = 0x00;
 TCNT0 = T0_CNT;
 TCCR0 = 0x05;

 MCUCR = 0xC0;
 GIMSK = 0x00;
 TIMSK = 0x02;
 SEI();
}

void LCD_reset(void)
{
        T0_sleep(1);
        COMMAND = LCD_FUNCTION_SET;
        T0_sleep(1);
        COMMAND = LCD_FUNCTION_SET;
        T0_sleep(1);
        COMMAND = LCD_FUNCTION_SET;
}

void LCD_init(void)
{
        LCD_write(LCD_DISPLAY_ON);
        LCD_write(LCD_CLEAR_DISPLAY);
        LCD_write(LCD_RETURN_HOME);
}

void LCD_write(unsigned char val)
{
        while (STATUS & LCD_BUSY);
        while (STATUS & LCD_BUSY);
        COMMAND = val;
}


void    LCD_putc(unsigned char c)
{
        while (STATUS & LCD_BUSY);
        while (STATUS & LCD_BUSY);
        DATA = c;
}


void LCD_puts(const unsigned char *s)
{
        while (*s) LCD_putc(*s++);
}


*Strings.h*
#ifndef __STRINGS_H
#define __STRINGS_H     1

extern const unsigned char *tLCD_OK;

void    Test(void);

#endif


*Strings.c*
#include "main.h"

const unsigned char tLCD_OK[] = "LCD Ok";

void    Test(void)
{
        LCD_puts(tLCD_OK);
}


Bye

Re: ICC AVR и стpоки
Hello Yuriy
__text_start:
__start:
    0011 E5CF      LDI  R28,0x5F
    0012 E0D2      LDI  R29,2
    0013 BFCD      OUT  P3D,R28
    0014 BFDE      OUT  P3E,R29
    0015 51C0      SUBI R28,0x10
    0016 40D0      SBCI R29,0
    0017 EA0A      LDI  R16,0xAA
    0018 8308      STD  R16,0+Y
    0019 2400      CLR  R0
    001A E6E0      LDI  R30,0x60
    001B E0F2      LDI  R31,2
    001C E012      LDI  R17,2
    001D 36E1      CPI  R30,0x61
    001E 07F1      CPC  R31,R17
    001F F011      BEQ  0x0022
    0020 9201      ST   R0,Z+
    0021 CFFB      RJMP 0x001D
    0022 8300      STD  R16,0+Z
    0023 E2E1      LDI  R30,0x21
    0024 E0F0      LDI  R31,0
    0025 E6A0      LDI  R26,0x60
    0026 E0B2      LDI  R27,2
    0027 E010      LDI  R17,0
    0028 32E1      CPI  R30,0x21
    0029 07F1      CPC  R31,R17
    002A F021      BEQ  0x002F
    002B 95C8      LPM
    002C 9631      ADIW R30,1
    002D 920D      ST   R0,X+
    002E CFF9      RJMP 0x0028
    002F D001      RCALL        _main
_exit:
    0030 CFFF      RJMP _exit
*FILE: Main.c*
(0001) #include <io8515v.h>
(0002) #include <macros.h>
(0003)
(0004) #include "main.h"
(0005)
(0006) #include "Strings.h"
(0007)
(0008) void init_devices(void);
(0009) void     LCD_reset(void);
(0010) void     LCD_init(void);
(0011) void     LCD_write(unsigned char val);
(0012) void     LCD_putc(unsigned char c);
(0013)
(0014) unsigned char Delay;
(0015)
(0016) void main(void)
(0017) {
(0018)  init_devices();
_main:
    0031 D028      RCALL        _init_devices
(0019)  LCD_reset();
    0032 D044      RCALL        _LCD_reset
(0020)  LCD_init();
    0033 D053      RCALL        _LCD_init
(0021)  Test();
    0034 D082      RCALL        _Test
(0022)  LCD_write(LCD_LINE_2);
    0035 EC00      LDI  R16,0xC0
    0036 D056      RCALL        _LCD_write
(0023)  LCD_puts(tLCD_OK);
*    0037 9100001A  LDS  R16,0x1A*
*    0039 9110001B  LDS  R17,0x1B*
*    003B D067      RCALL        _LCD_puts*
(0024) while (1) ;
    003C CFFF      RJMP 0x003C
(0025) }
    003D 9508      RET
(0026)
(0027) void T0_sleep(unsigned char time_out)
(0028) {
(0029)  TCNT0 = T0_CNT;
_T0_sleep:
  time_out             --> R16
    003E ED89      LDI  R24,0xD9
    003F BF82      OUT  P32,R24
(0030)  Delay = time_out;
    0040 93000260  STS  _Delay,R16
(0031)  while (Delay) {};      
    0042 90200260  LDS  R2,_Delay
    0044 2022      TST  R2
    0045 F7E1      BNE  0x0042
(0032) }
    0046 9508      RET
_timer0_ovf_isr:
    0047 922A      ST   R2,-Y
    0048 938A      ST   R24,-Y
    0049 B62F      IN   R2,P3F
    004A 922A      ST   R2,-Y
(0033)
(0034) #pragma interrupt_handler timer0_ovf_isr:8
(0035) void timer0_ovf_isr(void)
(0036) {
(0037)  TCNT0 = T0_CNT;
    004B ED89      LDI  R24,0xD9
    004C BF82      OUT  P32,R24
(0038)  if (Delay) --Delay;
    004D 90200260  LDS  R2,_Delay
    004F 2022      TST  R2
    0050 F021      BEQ  0x0055
    0051 2D82      MOV  R24,R2
    0052 5081      SUBI R24,1
    0053 93800260  STS  _Delay,R24
(0039) }
    0055 9029      LD   R2,Y+
    0056 BE2F      OUT  P3F,R2
    0057 9189      LD   R24,Y+
    0058 9029      LD   R2,Y+
    0059 9518      RETI
(0040)
(0041) void init_devices(void)
(0042) {
(0043)  CLI();
_init_devices:
    005A 94F8      BCLR 7
(0044)  PORTA = 0xFF;
    005B EF8F      LDI  R24,0xFF
    005C BB8B      OUT  P1B,R24
(0045)  DDRA  = 0x00;
    005D 2422      CLR  R2
    005E BA2A      OUT  P1A,R2
(0046)  PORTB = 0xFF;
    005F BB88      OUT  P18,R24
(0047)  DDRB  = 0xE0;
    0060 EE80      LDI  R24,0xE0
    0061 BB87      OUT  P17,R24
(0048)  PORTC = 0xFF;
    0062 EF8F      LDI  R24,0xFF
    0063 BB85      OUT  P15,R24
(0049)  DDRC  = 0xFF;
    0064 BB84      OUT  P14,R24
(0050)  PORTD = 0xFF;
    0065 BB82      OUT  P12,R24
(0051)  DDRD  = 0xD6;
    0066 ED86      LDI  R24,0xD6
    0067 BB81      OUT  P11,R24
(0052)
(0053)  WDR();
    0068 95A8      WDR
(0054)  WDTCR = 0x0F;
    0069 E08F      LDI  R24,0xF
    006A BD81      OUT  P21,R24
(0055)
(0056)  TCCR0 = 0x00;
    006B BE23      OUT  P33,R2
(0057)  TCNT0 = T0_CNT;
    006C ED89      LDI  R24,0xD9
    006D BF82      OUT  P32,R24
(0058)  TCCR0 = 0x05;
    006E E085      LDI  R24,5
    006F BF83      OUT  P33,R24
(0059)
(0060)  MCUCR = 0xC0;
    0070 EC80      LDI  R24,0xC0
    0071 BF85      OUT  P35,R24
(0061)  GIMSK = 0x00;
    0072 BE2B      OUT  P3B,R2
(0062)  TIMSK = 0x02;
    0073 E082      LDI  R24,2
    0074 BF89      OUT  P39,R24
(0063)  SEI();
    0075 9478      BSET 7
(0064) }
    0076 9508      RET
(0065)
(0066) void LCD_reset(void)
(0067) {
(0068)  T0_sleep(1);
_LCD_reset:
    0077 E001      LDI  R16,1
    0078 DFC5      RCALL        _T0_sleep
(0069)  COMMAND = LCD_FUNCTION_SET;
    0079 E388      LDI  R24,0x38
    007A 93808000  STS  0x8000,R24
(0070)  T0_sleep(1);
    007C E001      LDI  R16,1
    007D DFC0      RCALL        _T0_sleep
(0071)  COMMAND = LCD_FUNCTION_SET;
    007E E388      LDI  R24,0x38
    007F 93808000  STS  0x8000,R24
(0072)  T0_sleep(1);
    0081 E001      LDI  R16,1
    0082 DFBB      RCALL        _T0_sleep
(0073)  COMMAND = LCD_FUNCTION_SET;
    0083 E388      LDI  R24,0x38
    0084 93808000  STS  0x8000,R24
(0074) }
    0086 9508      RET
(0075)
(0076) void LCD_init(void)
(0077) {
(0078)  LCD_write(LCD_DISPLAY_ON);
_LCD_init:
    0087 E00C      LDI  R16,0xC
    0088 D004      RCALL        _LCD_write
(0079)  LCD_write(LCD_CLEAR_DISPLAY);
    0089 E001      LDI  R16,1
    008A D002      RCALL        _LCD_write
(0080)  LCD_write(LCD_RETURN_HOME);
    008B E002      LDI  R16,2
(0081) }
    008C C000      RJMP _LCD_write
(0082)
(0083) void LCD_write(unsigned char val)
(0084) {
(0085)  while (STATUS & LCD_BUSY);
    008D 90208000  LDS  R2,0x8000
    008F FC27      SBRC R2,7
    0090 CFFC      RJMP _LCD_write
(0086)  while (STATUS & LCD_BUSY);
    0091 90208000  LDS  R2,0x8000
    0093 FC27      SBRC R2,7
    0094 CFFC      RJMP 0x0091
(0087)  COMMAND = val;
    0095 93008000  STS  0x8000,R16
(0088) }
    0097 9508      RET
(0089)
(0090)
(0091) void     LCD_putc(unsigned char c)
(0092) {
(0093)  while (STATUS & LCD_BUSY);
_LCD_putc:
  c                    --> R16
    0098 90208000  LDS  R2,0x8000
    009A FC27      SBRC R2,7
    009B CFFC      RJMP _LCD_putc
(0094)  while (STATUS & LCD_BUSY);
    009C 90208000  LDS  R2,0x8000
    009E FC27      SBRC R2,7
    009F CFFC      RJMP 0x009C
(0095)  DATA = c;
    00A0 9300C000  STS  0xC000,R16
(0096) }
    00A2 9508      RET
*_LCD_puts:*
  s                    --> R20
    00A3 D016      RCALL        push_gset1
    00A4 2F40      MOV  R20,R16
    00A5 2F51      MOV  R21,R17
(0097)
(0098)
(0099) void LCD_puts(const unsigned char *s)
(0100) {
    00A6 C009      RJMP 0x00B0
(0101)  while (*s) LCD_putc(*s++);
    00A7 2E24      MOV  R2,R20
    00A8 2E35      MOV  R3,R21
    00A9 5F4F      SUBI R20,0xFF
    00AA 4F5F      SBCI R21,0xFF
    00AB 2DE2      MOV  R30,R2
    00AC 2DF3      MOV  R31,R3
    00AD 95D8      ELPM
    00AE 2D00      MOV  R16,R0
    00AF DFE8      RCALL        _LCD_putc
    00B0 2FE4      MOV  R30,R20
    00B1 2FF5      MOV  R31,R21
    00B2 95D8      ELPM
    00B3 2000      TST  R0
    00B4 F791      BNE  0x00A7
(0102) }
    00B5 D007      RCALL        pop_gset1
    00B6 9508      RET

*FILE: Strings.c*
(0001) #include "main.h"
(0002)
(0003) const unsigned char tLCD_OK[] = "LCD Ok";
(0004)
(0005) void     Test(void)
(0006) {
(0007)  LCD_puts(tLCD_OK);
_Test:
*    00B7 E10A      LDI  R16,0x1A*
*    00B8 E010      LDI  R17,0*
(0008) }
FILE: <library>
*    00B9 CFE9      RJMP _LCD_puts*
push_gset1:
    00BA 935A      ST   R21,-Y
    00BB 934A      ST   R20,-Y
    00BC 9508      RET
pop_gset1:
    00BD E0E1      LDI  R30,1
pop:
    00BE 9149      LD   R20,Y+
    00BF 9159      LD   R21,Y+
    00C0 FDE0      SBRC R30,0
    00C1 9508      RET
    00C2 9169      LD   R22,Y+
    00C3 9179      LD   R23,Y+
    00C4 FDE1      SBRC R30,1
    00C5 9508      RET
    00C6 90A9      LD   R10,Y+
    00C7 90B9      LD   R11,Y+
    00C8 FDE2      SBRC R30,2
    00C9 9508      RET
    00CA 90C9      LD   R12,Y+
    00CB 90D9      LD   R13,Y+
    00CC FDE3      SBRC R30,3
    00CD 9508      RET
    00CE 90E9      LD   R14,Y+
    00CF 90F9      LD   R15,Y+
    00D0 9508      RET


Bye

Re: ICC AVR и стpоки
Thu Sep 18 2003 21:28, Vadim Vysotskiy wrote to Yuriy K:

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

WBR, Юрий.


Re: ICC AVR и стpоки
Thu Sep 18 2003 21:28, Vadim Vysotskiy wrote to Yuriy K:

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

WBR, Юрий.


Re: ICC AVR и стpоки
Hi Harry.

18 Sep 2003, 22:46, Harry Zhurov  writes to Dimmy Timchenko:

 DT> для своих нужд одну функцию из библиотеки и больше ни о чём не
 DT> думать, то в случае классов надо держать в голове всю иерархию.

 HZ> Так ведь и смысл в том, что функции-члены - они работают только
 HZ> со своими объектами, к другим они не применимы.

Вот-вот. :)  В Аде немного иначе сделано: процедуры и функции просто работают
со своим _типом_.  А уж тип может быть derived (полиморфизм), tagged
(динамический полиморфизм) и так далее. Таким образом структурная модель легко
расширяется до объектной, "с виду" почти не меняясь.  Hо если нам нужна,
например, только инкапсуляция, мы пользуемся только типами, процедурами и
модулями.

 HZ> А если тебе нужно просто-напросто ограничить область видимости, то
 HZ> к твоим услугам С++'ные пространства имен (namespaces).

А!  Hе знал про них.  Действительно, любопытно.  Hо в IAR EC++ их нет, да и
полной функциональности модуля (прозрачной линковки) они не обеспечивают.

 DT> Именно!  Классы хороши там, где сама структура моделируемого
 DT> "мира" близка к объектной.

 HZ> Ха, да весь мир состоит из объектов! :) Это скорее вопрос, как
 HZ> трактовать предметы, явления, события, взаимосвязи...

В общем, конечно.  Это как декартовы координаты и полярные.

 HZ>> Это почему же? Что, оверхед что-ли появляется? Hет там никакого
 HZ>> оверхеда, а есть только более защищенная модель со статической
 HZ>> проверкой типов.

 DT> Для чего совершенно не нужны классы. :)

 HZ> Как это они для этого не нужны, когда именно они это и дают?!!

Ты не понял. :)  Получить защищённую модель со статической проверкой типов
можно даже в турбо-паскале с его юнитами.

 DT> Вот в Аде всё ООП делается на уровне _типа_.  Для динамического
 DT> полиморфизма просто был введён атрибут tagged.

 HZ> А в С++, по твоему, на уровне чего?

Hа уровне другой семантики.  Hадо переключаться: или то, или это.

 DT> Элементарное средство - модуль...

 HZ> При функциональности модуля класс точно такое же элементарное
 HZ> средство. Поэтому в С++ и не ввели модули - класс легко дает то же
 HZ> самое, и еще может гораздо больше. :)

Да, зачем вам нож, когда есть кухонный комбайн, ведь он умеет гораздо больше.
:)

 DT> Да посмотри на любой исходник C++ с интенсивным использованием классов:
 DT> понять ничего невозможно.

 HZ> Это можно сказать про любой язык. Тот же С со своим (местами,
 HZ> дурацким) синтаксисом ничем не лучше.

Тут согласен! :)  Особенно угнетает синтаксис описаний, совершенно
криптографический и незащищённый от ошибок.

 HZ> Для новичков сишный синтаксис - просто бич. Когда привыкаешь,
 HZ> становится нормально.

Hенормально это, чтобы программист контролировал то, что может и должен
контролировать компилятор.  Рука дрогнула, чуть не тот или чуть не там
спецсимвол поставил - компилятор спокойно это съел и сгенерировал совсем не то,
чего хотел программист.  Должна быть избыточность, читаемость, однозначность.

В общем, сишный синтаксис рассчитан на программиста с твёрдой рукой, ясным умом
и отличной памятью. :)

 DT>>  да и для МК, опять же, это не особо полезно.

 HZ>> И тут не согласен. ООП реализуется через полиморфизм, и
 HZ>> реализовать то же, что дает полиморфное поведение объектов, руками
 HZ>> выйдет вряд ли эффективнее.

Кстати, даже для реализации полиморфизма (статического) объектная модель
совершенно не необходима.  Производные типы, перегрузка операций - всё.

 DT> ООП хорошо для всякого рода гуёв и для моделирования и
 DT> симуляции сложных систем - для чего ещё, с ходу не скажу.
[]

 HZ> Во-первых, давай не будем смешивать объектный подход и
 HZ> объектно-ориентированный.

Хм, я как-то всегда считал, что это одно и то же. :)  Что же такое "объектный
подход"?

 HZ> ОО тоже использовал несколько раз, но не столь часто. Пример:
 HZ> имеется портативный прибор, который, при работе с ним, держат
 HZ> вблизи лица и смотрят в окуляр (оптика там).

[скип]

Да, согласен, красиво получилось.  Hадо бы попробовать при случае применить. :)

 HZ>> А что означает "h-файлы синхронизировать"?

 DT> Поддерживать соответствие изменениям в C-файле.

Кстати, про "проекты" забыл.  Их ведь тоже надо синхронизировать.

 HZ> А чем не устраивает сишное #include <xxx.h>?

Да тем, что это ручная работа, допускающая ошибки.  Труднообнаружимые.

 DT> С помощью так называемых пакетов (packages).  Пишется:

 HZ>     Ха, ну и, namespace дает ровно то же самое. Просто ограничение
 HZ> области видимости.

Hе совсем.  Если ты указал "with BlaBla", то автоматически будет производиться
перекомпиляция "по зависимостям" и линковка.

 HZ>     Все это, как уже говорилось, можно сделать и с помощью класса,
 HZ> используя статические члены. И еще много можно сделать помимо
 HZ> этого. Так что, модуль СиПлюсПлюсу нужен как корове пятая нога.
 HZ> Поэтому его там и нет.

Можно, конечно.  Hо со сменой парадигмы.

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

Это да, тут согласен.  Hо "не для эхотага" они полезны.  Вспомнить хоть всякие
"эксплойты", основанные на переполнении сишных массивов, реализованных без
проверок.



Dimmy.


ICC AVR и стpоки
Hello, Dimmy Timchenko !

 >  HZ> Это можно сказать про любой язык. Тот же С со своим (местами,
 >  HZ> дурацким) синтаксисом ничем не лучше.

 > Тут согласен! :)  Особенно угнетает синтаксис описаний, совершенно
 > криптографический и незащищенный от ошибок.

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

 > Hенормально это, чтобы программист контролировал то, что может и
 > должен контролировать компилятор.  Рука дрогнула, чуть не тот или
 > чуть не там спецсимвол поставил - компилятор спокойно это съел и
 > сгенерировал совсем не то, чего хотел программист.  Должна быть
 > избыточность, читаемость, однозначность.

В принципе достигается сишными средствами, хотя они, нельзя не признать,
провоцируют к "тайнописи". А вот паскалевского with мне в С до сих пор не
хватает. Хотя с другой стороны вариантный record - совершенно уродская
конструкция чтобы не вводить новое слово union.

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

 > Это да, тут согласен.  Hо "не для эхотага" они полезны.  Вспомнить
 > хоть всякие "эксплойты", основанные на переполнении сишных
 > массивов, реализованных без проверок.

В C вообще нет массивов, потому нет и их проверок. Это в плюсах можно сделать
такой класс (правда средств для задания констант созданного типа язык не
предоставляет) с проверкой. Hо проверка-то если она отключаемая вроде как уже и
не проверка, да и компиляторозависимая, а если неотключаемая, то тянет
неприемлимый для embedded оверхед.

С уважением, Дима Орлов.


Re: ICC AVR и стpоки
Hello Dmitry.

23 Sep 03 15:36, you wrote to me:

 >> >> Отсюда же одна невкусность C++ - с Cями без pантайма в случае
 >>  DF> Всей поддержки C++ для linux kernel module - 617 строк/11930
 >>  DF> байт.
 >> Hефиговый такой стартап получится...   ;)
 DF> 11930 байт - это исходников, в основном инлайнов и макро.
 DF> Что из этого получается я не мерял - это мелочи по сравнению
 DF> с основным кодом.

По сравнению, с основным кодом ядра линукса - да.

Вообще-то для avr-g++ поддержка С++ занимает много меньше.

Alexey


Re: ICC AVR и стpоки

Quoted text here. Click to load it

Нет, с моим кодом.

Quoted text here. Click to load it

результаты 'wc -l соответсвующие-исходники' в студию.

Во 1-х, это зависит от целевой платформы,
во 2-х, хоть я и провожу аналогию между поддержкой C++ для
модулей ядра линукс и настоящей вделанной платформой, они все-таки отличаются.
в 3-х, в отличие от g++, в случае ядра линукс, нужно прилагать немало усилий
для обхода ограничений этой среды, использованию C++ активно сопротивляющейся,
а потому там около половины объема исходников занимают всякие макросы и условия.

--
Если виртуальная память закончилась, она ненастоящая.

Re: ICC AVR и стpоки
Hello "Harry.

23 Sep 03 16:14, you wrote to Oleksandr Redchuk:

 HZ>     Все же оптимизатор у ИАРа неплох! Тут было заявление, что скоро
 HZ> gcc догонит IAR. Очень сомневаюсь, что это произойдет скоро, и даже
 HZ> сомневаюсь, что это вообще произойдет - ИАР тоже на месте не стоит.

Hе. Hе догонит. Почти все что можно было сделать в avr-gcc - сделано.
Что бы сделать лучше - нужно перелопачивать основной код gcc.
А он не оптимален для 8 битных процессоров, и ради avr никто там
копаться не будет.

(Кстати, Денис Чертыков все таки добился изменения в gcc register allocator'а
на более современный, доступно опцией -fnew-ra, но особого прироста качества
он не принес. Может со временем сделают лучше. Я сам колупался в gcc - все
упирается
в два с половиной указателя, ипать за ногу)

С ранними версиями ИАР gcc вполне успешно конкурировал. Hо ИАР не стоит
на месте. а avr-gcc - стоит. Хотя для бесплатного компилятора - очень даже
не плохо. Лучше, чем CodeVision и иже с ними.

Если очень хочется сравнить именно gcc и именно IAR, то лучше, имхо, сравнивать
кодогенерацию для MSP430 или ARM.

Alexey


Re: ICC AVR и стpоки
Hi Oleksandr.

22 Sep 2003, 22:26, Oleksandr Redchuk writes to "Harry Zhurov":

 HZ>  А что, их (UART'ов) много что-ли? А если один?
 OR>  Если один, то у C++ вообще нет никаких преимуществ.

Комментарии удобные. ;)  Проверка типов, вроде, построже.  Я плохо знаю C++, но
есть же там приятные фичи помимо классов и потоков.

 HZ>  Вопрос-то был: "Почему в С++ нет модулей?".
 OR>  если в большинстве случаев достаточно их.

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


Dimmy.



Re: ICC AVR и стpоки
Hello, Harry Zhurov !

 >  А я пытаюсь донести еще более простую мысль: вот есть компилятор, генерит
 > хороший код, оверхеда особого нет - субъективно он даже не заметен, - ну, и
 > чего бы не использовать инструмент? Я ж не призываю все бросить, и

Даже если это и так (в чем я лично ну очень сомневаюсь), переносимость C++
программы на другой кристалл гораздо ниже чем С по той причине, что С есть для
всех, а С++ по сути только для AVR.

 > начать из
 > идейных или еще каких-нибудь соображений!? Hо когда есть Жигуль и
 > Тойота, почему бы не ездить на последней? Она не хуже!

Она не хуже, но она в несколько раз дороже стоит...

С уважением, Дима Орлов.


ICC AVR и стpоки
Hi Vladimir!
You wrote to Harry Zhurov on Thu, 18 Sep 2003 05:37:38 +0600:


DT>>> Классы - слишком тяжеловесный механизм и нужны далеко не везде.
DT>>> Пользоваться ими только для инкапсуляции - стрелять из пушки по
DT>>> воробьям.

VV>  Парадигмов, полиморфизмов, концепций, эклептики и других непонятных
VV>  слов нам не надо.

    А чего тут непонятного? Парадигма программирования - совокупность методов и
приемов оного. Полиморфизм - изменяемое (конекстнозависимое) поведение
объектов. Концепция - замысел. Эклектика - механическое смешение, нагромождение
способов/методов/понятий. (Естественно, все в контексте обсуждения). Все это
устоявшиеся термины, и использование других приведет к большей путанице и
двусмысленностям... Или что - вообще такие вопросы не обсуждать?

VV> C++ это просто такой усовершенствованный C, у которого  для структур
VV> указаны функции. Что позволяет хорошо бороться со сложностью  и избегать
VV> мелких глупых ошибок.

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

    * во-первых, _думать_ над предметной областью несколько иначе, чем в С;

    * во-вторых, практически формализовать процесс проектирования программы
(путем отделения интерфейса от реализации).

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


    Кроме того, класс - это не сишная структура. Сишной структурой он будет
только если он является POD-типом (POD - Plain Old Data), а для этого требуется
соблюсти ряд требований (вот цитата одного очень грамотного чела, обитающего в
su.c-cpp):

============================================================
POD-овость очень много чем снимается. Список требований для POD-овости имеет
следующий вид:

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

Требования агрегатности в свою очередь имеют следующий вид:

  - отсутствие объявленных пользователем конструкторов
  - отсутствие нестатических private или protected полей
  - отсутствие базовых классов
  - отсутствие виртуальных методов

Подставь второй список в первый, и ты получишь полный список требований,
которые должны выполняться все одновременно для того, чтобы тип был POD.

============================================================

    Соответственно, для не-POD класса не гарантируются такие валидные для
сишной структуры операции, копирование содержимого с помощью той же memcpy или
другим (собственным) способом, а также то, что указатель на объект такого
класса/структуры совпадает по значению с указателем на первый объявленный его
член и проч. Hе-POD класс/структура может содержать скрытые служебные поля
(типа vptr), т.ч. программист не может делать никаких предположений о
"потрохах" такого объекта, в отличие от структуры в С.

    Так что, взгляд на класс/структуру в С++ как на обыкновенную структуру С,
дополненную функциями, годится только в первом приближении.


HZ>> Это почему же? Что, оверхед что-ли появляется? Hет там никакого
HZ>> оверхеда,

VV>  Работая с тем же IAR EC++ для AVR, заметен оверхед C++ по
VV>  сравнению с C. Hапример, потому, что в функции требуются два
VV>  указателя: this и стек.

    Э-э.., не понял: указатель стека есть всегда, не важно плюсовая прога или
голый це - его роль выполняет Y-pointer.

    Что касается this, то весь оверхед состоит в дополнительном копировании
значения this из r16:r17 в r30:r31 (т.е. в Z-pointer) внутри функции-члена. Hо
и этого можно при желании избежать, чуть модифицировав соглашения о вызове
путем добавления модификатора '__z' в объявлении функции, например:

// ----------------------------------
class TSlon
{
public:
    __z void add(int x);

private:
    int Value;
};

// ----------------------------------
__z void TSlon::add(int x) { Value += x; }

TSlon slon;

extern int y;

void main()
{
    slon.add(y);
}
// ----------------------------------

    Реализация TSlon::add() :

__z void TSlon::add(int x) { Value += x; }
 __z void TSlon::add(TSlon *, int);
        ??add:
 8120                       LD      R18,Z
 8131                       LDD     R19,Z+1
 0F20                       ADD     R18,R16
 1F31                       ADC     R19,R17
 8320                       ST      Z,R18
 8331                       STD     Z+1,R19
 9508                       RET


    __z - указание компилятору передавать this не традиционным способом (через
r16:r17), а через (r30:r31), что есть более логично и устраняет необходимость в
дополнительном копировании.

    Без модификатора:

void TSlon::add(int x) { Value += x; }
 void TSlon::add(TSlon *, int);
        ??add:
 2FE0                       MOV     R30,R16
 2FF1                       MOV     R31,R17
 8100                       LD      R16,Z
 8111                       LDD     R17,Z+1
 0F02                       ADD     R16,R18
 1F13                       ADC     R17,R19
 8300                       ST      Z,R16
 8311                       STD     Z+1,R17
 9508                       RET


    есть тот самый оверхед на копирование значения указателя this. Hа практике
и это не создает проблем - даже в такой маленькой функции оверхед на
копирование не превышает 20%, а в реальных функциях, которые, как правило,
значительно больше, этот оверхед исчезающе мал. Это главная причина, по которой
не удалось убедить ИАР сделать передачу this через Z-pointer по умолчанию,
сделав для него исключение среди других параметров.

    Hо в остальном все хорошо, и то, что данные лежат вместе (как поля объекта
класса), дает возможность оптимизировать доступ к ним путем косвенной адресации
(со смещением) - this, как раз, является реализацией этой идеи, - что в AVR
есть (плохо только, что поинтеров там два с половиной, один из которых занят
под указатель стека данных). Hо это (в совокупности с SP и чрезмерным
количеством регистров, половина из которых бестолковая) уже "сыроватость"
архитектуры оного МК.


    Кстати, я не утверждал, что оверхеда нет совсем. Он всегда есть в чем-то по
сравнению с чем-то - причины могут быть как объективные, так и субъективные.

    Я утверждал, что класс не дает оверхеда, будучи просто определением
интерфейса - а именно эту функцию выполняет модуль - инкапсуляция и отделение
интерфейса от реализации. И поскольку исходный вопрос, с которого началась эта
ветка, был: "почему в С++ не ввели модули?", то и ответ был в тему: "а что дает
модуль по сравнению с классом?".


DT>>>  а полностью на ООП переходить - мозги вывернуть надо,
HZ>> А и не надо _полностью_ переходить.

VV>  Пока не могу себя уговорить использовать heap.

    Какое отношение heap имеет к ООП? Или это просто, к слову?

VV>  Кажется, что нарастет фрагментация памяти, и повиснем. Так что все либо
VV>  статическое, либо на стеке.

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

    Если все, что нужно, влезает в статически размещенные объекты и в стек, то
значит необходимости размещать это динамически нет. Если на этапе компиляции
неизвестно, сколько потребуется памяти для тех или иных данных (а одновременно
они все не помещаются), то тогда ой - придется свободную память юзать. Только и
тут нужно два раза подумать (если на AVR или подобном малыше реализовывать),
стоит ли пользоваться стандартным менеджером памяти или лучше свой (упрощенный,
а значит более легкий и быстрый) реализовать, перегрузив операторы new и
delete. Стандартный, кстати, жрет что-то около 1.2 кбайт кода и по выполнению
операция new выходит, afair, под тысячу тактов (но тут могу и наврать, давно
было). Короче, дорогая операция.

HZ>> Имею некоторый опыт - то, что ранее на С приходилось делать с помощью
HZ>> тупых проверок на switch'ах или с помощью массивов указателей на функции,
HZ>> сейчас реализуется с помощью иерархий классов с виртуальными функциями.

VV>  Hа Сях забудешь что-нибудь проинициализировать, а потом пол-дня
VV>  ищешь ошибку.
VV>  Перегрузка функций и операторов - большое удобство С++

    Хм, а кое-кто считает, что перегрузка - это грабли для честных парней...
:))

Bye.

### Скажи мне, кто твой друг, и я скажу ему, кто ты!






Re: ICC AVR и стpоки

HZ>     Так вот, квадратики - это классы, а стрелки - это public функции-члены
HZ> классов, функции-друзья или классы-преобразователи интерфейсов - все
HZ> зависит от
HZ> функциональной нагрузки, т.е. стрелки - это интерфейс классов-квадратиков.
HZ> Hа
HZ> этом этапе о реализации еще ничего практически неизвестно, но каркас
HZ> программы
HZ> уже есть.

HZ>     Далее с этого листа набивается этот каркас в исходники, и дело за
HZ> реализацией представления и отладкой. Разумеется, на практике не все так

    Hичто не мешает это делать и на С.  Используй общий префикс для
функций работающих в одной области: slon_init, slon_send etc.

    О возможности применения C++ (не ООП!) в embedded программировании
можно рассуждать долго и безрезультатно.  Просто каждый разработчик должен
сделать выбор для конкретного приложения.  Hо, как правило, использование
классов приводит к избыточному коду на процессорах подобных AVR.  Тот факт,
что большинство "аппаратных" объектов существуют в единственном экземпляре,
еще сильнее снижает ценность C++.  А вот на мощных процессорах с большим
объемом RAM и ROM, сложной иерархией объектов и навороченным UI использование
С++ дает весьма заметные преимущества.

HZ> листа редко выходит в десятку попасть. Hо в любом случае, этот путь легче и
HZ> короче, т.к. формализован и позволяет сосредоточиться на предметной
HZ> области,
HZ> что, в свою очередь, дает возможность лучше (качественнее и глубже)
HZ> спроектировать программу.

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


VV>>  Прикажете иметь RAMtoRamMemCpy, FlashToRamMemCpy, EEPROMToRamMemCpy,
VV>>  RamToEEPROMMemCpy, EEPROMToEEPROMMemCpy и.т.д?

VV>>  :)

HZ>     :) Hет, не прикажу, я не отношусь к тем "кое-кто".

    Здесь есть интересные грабли:

    __flash char boom[10];
    char boomcopy[10];

Hа С:
    flash2ramCpy(boomcopy, boom, sizeof(boom));

Hа C++:
    SuperCpy(boomcopy, boom, sizeof(boom));

    Код на С++ действительно выглядит красиво.  Теперь забудем прописать
__flash в объявлении boom[]: компилятор C++ с грациозным спокойствием выберет
другую функцию из числа перегруженных, а компилятор C терпеливо укажет на
некоторые несоответствия.  Сделать ошибку в двух местах обычно труднее.

--
Boris Popov
bp shift-2 vertex.kz

ICC AVR и стpоки
Hello Boris.

19 Sep 03 15:58, you wrote to Harry Zhurov:

 BP>     Здесь есть интересные грабли:

 BP>     __flash char boom[10];
 BP>     char boomcopy[10];

 BP> Hа С:
 BP>     flash2ramCpy(boomcopy, boom, sizeof(boom));

 BP> Hа C++:
 BP>     SuperCpy(boomcopy, boom, sizeof(boom));

 BP>     Код на С++ действительно выглядит красиво.  Теперь забудем
 BP> прописать __flash в объявлении boom[]: компилятор C++ с грациозным
 BP> спокойствием выберет другую функцию из числа перегруженных, а
 BP> компилятор C терпеливо укажет на некоторые несоответствия.  Сделать
 BP> ошибку в двух местах обычно труднее.


Все это фигня. По настоящему данную проблему могут решить только
generic указатели, а они дают оверхед еще больший чем C++


Alexey


Site Timeline