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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

VladislavS, Вы пропустили мой классический пример кривизны ad-hoc полиморфизма? Повторить?

И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.
Последний раз редактировалось ПростоНуб Вс сен 29, 2019 12:06:55, всего редактировалось 1 раз.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18790
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709280#p3709280"]VladislavS, Вы пропустили мой классический пример кривизны ad-hoc полиморфизма? Повторить?[/uquote]С дуру и хрен сломать можно.
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709280#p3709280"]И если Вы не считаете полиморфизм в C++ синтаксическим сахаром, то приведите пример алгоритма, который не реализуем без использования полиморфизма другими средствами языка.[/uquote]Списки типов.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

VladislavS, при чем тут списки типов? Это алгоритм?
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.

Добавлено after 11 minutes 22 seconds:
VladislavS, с дуру можно все. Но когда конструкция языка повышает вероятность возникновения этого "с дуру", ее и называют спорной. Так снижение трудозатрат на написание кода, легко может перекрыться повышением трудозатрат при отладке и сопровождении кода. И я сам на это многократно нарывался.

Если Вы действительно считаете даже классический пример полиморфизма в С++ "дуростью", то что же можно сказать о боле сложных его применениях )))
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709313#p3709313"]VladislavS, при чем тут списки типов? Это алгоритм?
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.[/uquote]Я, пожалуй, отвечу на все три вопроса одним кусочком кода. В нём и списки типов, и сложные алгоритмы, и полиморфизм, и синтаксический сахар. Инициализация всех ног контроллера разом.

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

ConfigList
< PinMode::PushPull_MediumSpeed<0>,               
    PA_3, PA_5, PA_7, PA_12, 
    GpioB<0x3F>, PB_13, PB_14, PB_15,
    GpioC<0xF>, PC_5, PC_6, PC_8, PC_9, PC_15,
  PinMode::Floating,               
    PA_0, PA_1, PA_2, PA_4, PA_6, PA_10, PA_11,
    PB_6, PB_12, PC_4, PC_7,
  PinMode::PullDown, 
    PA_13, PA_14,
  PinMode::AF_PushPull_MediumSpeed,               
    PA_8, PA_9, PA_15,
  PinMode::AF_OpenDrain_MediumSpeed, 
    PB_8, PB_9, PB_10, PB_11,
  PinMode::AF_PushPull_HighSpeed, 
    PB_7,
  PinMode::Floating, 
    CfgCmd::AllUnusedPins 
>::mode();
[uquote="ARV",url="/forum/viewtopic.php?p=3709286#p3709286"]имхо, это не сделает мир программирования лучше.[/uquote]Уже сделало, а будет ещё лучше.
Приложу ещё один кусочек кода. Класс, поддерживающий все микросхемы eeprom 24Сxx. Да, его было можно сделать и без шаблонов, и без constexpr, и без перегрузок функций. Но я как представлю это безудержный поток #ifdef-ов...
Спойлер

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

#pragma once

namespace EEPROM_AT24C
{
  
enum class EEType { AT24C01=0, AT24C02=1, AT24C04=2, AT24C08=3, AT24C16=4, 
                    AT24C32=5, AT24C64=6, AT24C128=7, AT24C256=8, AT24C512=9, AT24CM01=10, AT24CM02=11 };

struct EEParams
{
  uint32_t size;
  uint32_t page_size;
};

static constexpr EEParams AllParams[12] =  //Объём памяти и размер страницы для всех чипов 24Cxx
{ {128,8}, {256,8}, {512,16}, {1024*1,16}, {1024*2,16}, 
  {1024*4,38}, {1024*8,32}, {1024*16,64}, {1024*32,64}, {1024*65,128}, {1024*128,256}, {1024*256,256} };

template<typename TI2C, typename TDelay, EEType eeType, uint8_t HW_ADR>
class EE_24C
{
  public:    
    _inline_ constexpr EE_24C(){};
    
    static _inline_ bool ReadByte(uint16_t adr, uint8_t *data)
    {
      if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
      { //Микросхемы с двухбайтовой адресацией  + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
        return TI2C::ReadReg(new_adr,(uint16_t)adr, data, (uint8_t)1);
      }
      else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))        
      { //Микросхемы с двухбайтовой адресацией 
        return TI2C::ReadReg(hw_adr,(uint16_t)adr, data, (uint8_t)1);
      }
      else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
      { //Микросхемы с однобайтовой адресацией  
        return TI2C::ReadReg(hw_adr,(uint8_t)adr, data, (uint8_t)1);
      }
      else
      { //Микросхемы с адресацией 1 байт + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
        return TI2C::ReadReg(new_adr,(uint8_t)adr, data, (uint32_t)1);     
      }
    }
        
    static _inline_ bool WriteByte(uint16_t adr, uint8_t data)
    {
      if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
      { //Микросхемы с двухбайтовой адресацией  + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
        return TI2C::WriteReg(new_adr,(uint16_t)adr, &data, (uint8_t)1);
      }
      else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
      { //Микросхемы с двухбайтовой адресацией  
        return TI2C::WriteReg(hw_adr,(uint16_t)adr, &data, (uint8_t)1); 
      }
      else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
      { //Микросхемы с однобайтовой адресацией  
        return TI2C::WriteReg(hw_adr,(uint8_t)adr, &data, (uint8_t)1);
      }
      else
      { //Микросхемы с адресацией 1 байт + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
        return TI2C::WriteReg(new_adr,(uint8_t)adr, &data, (uint8_t)1);      
      }      
    }
    
    static _inline_ bool ReadData(uint32_t adr, uint8_t *data, uint32_t length)
    {
      if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
      { //Микросхемы с двухбайтовой адресацией  + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
        return TI2C::ReadReg(new_adr,(uint16_t)adr, data, (uint32_t)length);
      }
      else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))        
      { //Микросхемы с двухбайтовой адресацией         
        return TI2C::ReadReg(hw_adr, (uint16_t)adr, data, (uint32_t)length);
      }
      else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
      { //Микросхемы с однобайтовой адресацией  
        return TI2C::ReadReg(hw_adr,(uint8_t)adr, data, (uint8_t)length);
      }
      else
      { //Микросхемы с адресацией 1 байт + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
        return TI2C::ReadReg(new_adr,(uint8_t)adr, data, (uint32_t)length);     
      }
    }
    
    static _inline_ bool WriteData(uint32_t adr, uint8_t *data, uint32_t length)
    {
      if( (((uint32_t)adr) + ((uint32_t)length)) > eeparams.size) return false; 
      uint32_t page_shift = adr&(eeparams.page_size-1);
      //Шаг 1: Запись начального кусочка
      uint32_t data2write = length<(eeparams.page_size-page_shift) ? length : (eeparams.page_size-page_shift);
      if(!WriteDataInOnePage(adr,data,data2write)) return false;   
      length -= data2write;
      adr+=data2write;
      data+=data2write;
      //Шаг 2: Запись остальных страниц (они уже выровнены)
      while(length)
      {
        TDelay::template Delay_ms<5>(); //Ждать пока предыдущая страница не запишется
        data2write = length<eeparams.page_size ? length : eeparams.page_size;
        if(!WriteDataInOnePage(adr,data,data2write)) return false;
        length -= data2write;
        adr+=data2write;
        data+=data2write;
      }
      return true;
    }
    
  private:    
    static constexpr uint8_t hw_adr=0xA0+((HW_ADR&0x7)<<1); 
    static constexpr EEParams eeparams  = AllParams[uint32_t(eeType)];
    
    static _inline_ bool WriteDataInOnePage(uint32_t adr, uint8_t *data, uint32_t length)
    {
      if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24CM01))
      { //Микросхемы с двухбайтовой адресацией  + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>16)&0x3)<<1);
        return TI2C::WriteReg(new_adr,(uint16_t)adr, data, (uint32_t)length);
      }
      else if constexpr (uint32_t(eeType)>=uint32_t(EEType::AT24C32))
      { //Микросхемы с двухбайтовой адресацией  
        if constexpr(eeparams.page_size>255)
          return TI2C::WriteReg(hw_adr,(uint16_t)adr, data, (uint32_t)length);
        else
          return TI2C::WriteReg(hw_adr,(uint16_t)adr, data, (uint8_t)length); 
      }
      else if constexpr(uint32_t(eeType)<=uint32_t(EEType::AT24C02))
      { //Микросхемы с однобайтовой адресацией  
        return TI2C::WriteReg(hw_adr,(uint8_t)adr, data, (uint8_t)length);
      }
      else
      { //Микросхемы с адресацией 1 байт + биты в HW_ADR
        uint8_t new_adr = hw_adr + (((adr>>8)&0x3)<<1);
        return TI2C::WriteReg(new_adr,(uint8_t)adr, data, (uint8_t)length);      
      }
    }      
};

} // namespace EEPROM_AT24C
Последний раз редактировалось VladislavS Вс сен 29, 2019 13:24:48, всего редактировалось 2 раза.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

VladislavS, Вы утверждаете что тоже самое нельзя сделать без использования полиморфизма? :shock:
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709330#p3709330"]VladislavS, Вы утверждаете что тоже самое нельзя сделать без использования полиморфизма? :shock:[/uquote]Как говорил Reflector, у вас сейчас обязательно найдётся неотложное дело и мы не увидим хотя бы близкой альтернативы.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

ПростоНуб, А без демагонии? Вы утвердете, что проинициализировать пины МК без использования полиморфизма на C++ невозможно?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Демагогией занимаетесь как раз вы, а я конкретный пример привёл. Перекрыть который, я так понимаю, не чем?
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709253#p3709253"]я же писал выше, что параметрический полиморфизм на мономорфном ядре есть лишь синтаксический сахар. Очень спорно, перевешивают ли его достоинства его недостатки.
Праметрический полиморфизм без недостатков есть, например, в ML, но его обсуждение явно выходит за рамки темы.[/uquote]
Недостатки есть везде, но если брать более современные языки родственные С, то там почти везде есть дженерики. В С++ есть шаблоны и это активно развивающееся направление языка, что явно указывает на его полезность, дженерики в разных реализациях есть в C#, Java, D, Rust, причем в части языков необходимость их добавления осознали на сразу. В Gо пока ничего такого нет и это была ошибка, насколько знаю добавление обобщенного программирования в Go уже запланированно вместе с контрактами... А если что-то забраковывать на основании имеющихся недостатков, то вообще языков программирования не останется :)
Вы вообще знаете, что такое синтаксический сахар?
Так вот и приведите пример алгоритма, которые не реализуем на C++ без использования полиморфизма.
Зачем мелочиться, можно из языка выкинуть почти все, главное чтобы он остался полным по Тьюрингу, и все выкинутое будет синтаксическим сахаром :)
Последний раз редактировалось Reflector Вс сен 29, 2019 13:43:10, всего редактировалось 1 раз.
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

VladislavS, демагогия, это когда на прямой вопрос вместо "да" или "нет", отвечают что угодно, лишь бы на вопрос не ответить. Так да или нет?

Добавлено after 6 minutes 34 seconds:
Reflector, прошу прощения, но я называю ad-hoc полиморфизм спорным преимуществом, а не ненужным.
Почему Вы не ответили на мой прямой вопрос к Вам в классическом примере полиморфизма в C++? Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?

Добавлено after 9 minutes 58 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3709342#p3709342"]можно из языка выкинуть почти все, главное чтобы он остался полным по Тьюрингу, и все выкинутое будет синтаксическим сахаром[/uquote]
Вы совершенно правы. По определению синтаксического сахара - это именно так!
Другое дело, что, например, ситаксический сахар в виде оператора for лишен недостатков, а синтаксический сахар в виде ad-hoc полиморфизма такими недостатками обладает.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709344#p3709344"]Почему Вы не ответили на мой прямой вопрос к Вам в классическом примере полиморфизма в C++? Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?[/uquote]
Функция сравнивает то, что ей передают, если это сишные строки передаваемые как указатели, то программист должен понимать какой будет результат, тем более в описании написано, что для сравнения используется оператор '<'. Если он не понимает, то и без всяких шаблонов может на С написать практически то же самое:

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

char *s = ("last" > "first") ? "last" : "first";
И что С теперь плохой, все дружно перебираемся на паскаль? :)

ps. Лично у меня max() совершенно не ассоциируется с функцией сравнивающей строки...
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Reflector, наконец-то! А для того, чтобы понимать, нужно исследовать перегрузку оператора сравнения для классов используемых объектов. А если этот код писало десять человек три года назад, быстрее будет без всякого полиморфизма написать свое сравнение, чем копаться в тысячах строках кода, врубаясь, подходит реализованная кем-то когда-то перегрузка для данного случая или нет.
Даже в описанном мной классическом случае совершенно неоднозначно, требуется сравнение указателей или строк. Иногда важно одно, иногда - другое.
Я нигде не писал "плохой", в отличии от Вас. Я только пытаюсь предупредить читателей данной темы, особенно новичков, что ad-hoc полиморфизм в C++ имеет весомые недостатки. Его использовать допустимо только хорошо отдавая себе отчет, что вернувшись к своему же коду через год-другой понадобится углубляться в изучение реализации всех перегрузок давно забытого кода.
В общем случае, лучше начинающим вообще на C++ полиморфизмом не увлекаться. Код будет прозрачней и проще.
Друг Кота
Аватара пользователя
Сообщения: 3386
Зарегистрирован: Пн окт 11, 2010 19:00:08

Сообщение Мурик »

Reflector писал(а):все дружно перебираемся на паскаль?
Лучше на бейсик. :) :idea:
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

Мурик, тебе давно пора. Сидел на барсиках и нечего было слезать. Только СД мог такое за переход на барсик ляпнуть...
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="Reflector",url="/forum/viewtopic.php?p=3709209#p3709209"]Как ты на С будешь делать подобные проверки?[/uquote]
Не буду. Это - блажь!
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709344#p3709344"]Так что будет сравнивать полиморфный шаблон? Указатели или то, на что они указывают? А если речь будет уже о сложных объектах, с тысячами срок кода их реализации?[/uquote]Средства языка позволяют понять что за тип передаётся в шаблон и либо подобрать ему соответствующий метод сравнения, либо assert-нуть. Если программист этого не сделал, то он ССЗБ.

Добавлено after 7 minutes 10 seconds:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=3709507#p3709507"]Не буду. Это - блажь![/uquote]Ваше мнение очень важно для нас! :)
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

VladislavS, и что будет сравниваться в моем простейшем примере? )))
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3709595#p3709595"]и что будет сравниваться в моем простейшем примере? )))[/uquote]
Если бы изначально в С параллельно с char существовал еще один 8-ми битный тип, условный byte, и char использовался только для строк, то max() принимая char* могла бы исходить из того, что это строки, сравнивать их нужно как строки и нет никаких проблем. Внимание вопрос: а при чем тут параметрический полиморфизм на мономорфном ядре? :) Ты пытаешься убедить, что проблема в С++, т.к. полиморфизм там какой-то недоделанный, но даже идеальная реализация полиморфизма бесполезна когда нельзя сказать строка перед нами или что-то другое...
Собутыльник Кота
Аватара пользователя
Сообщения: 2723
Зарегистрирован: Пт сен 07, 2018 20:20:02
Откуда: деревня в Тульской губернии

Сообщение ПростоНуб »

Reflector, я никого не убеждаю, я просто констатирую факт, что в С++ нет параметрического полиморфизма, как, например, в ML. Вместо этого есть синтаксический сахар ad-hoc полиморфизма поверх мономорфного ядра. Именно из этого мономорфного ядра и проистекают все недостатки полиморфизма в C++. Полиморфизм в C++ не может быть "доделанным". Для этого нужно сменить ядро языка на полиморфное, но тогда это будет уже другой язык )

Добавлено after 18 minutes 38 seconds:
P.S. У меня складывается ощущение, что многие просто не понимают, что такое полиморфизм. На удивление, в Вики очень неплохая статья по этому поводу.
Ответить

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