На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (81) « Первая ... 78 79 [80] 81   ( Перейти к последнему сообщению )  
> Текущий Стандарт С++ и перспективы его развития
    Наткнулся на описание функции из книжки AMD (BIOS and Kernel Developer’s Guide for the AMD Athlon™ 64 and AMD Opteron™ Processors):
    ExpandedWrap disabled
      (int,int,int) TranslateSysAddrToCS((uint32)SystemAddr){
      int CSFound, NodeID, CS, F1Offset, F2Offset, Ilog;
      uint32 IntlvEn, IntlvSel;
      uint32 DramBase, DramLimit, DramEn;
      uint32 HoleOffset, HoleEn;
      uint32 CSBase, CSLimit, CSMask, CSEn;
      uint32 InputAddr, Temp;
      CSFound = 0;
      for(NodeID = 0; NodeID < 8; NodeID++){
          F1Offset = 0x40 + (NodeID << 3);
          DramBase = Get_PCI(bus0, dev24 + NodeID, func1, F1Offset);
          DramEn = DramBase & 0x00000003;
          IntlvEn = (DramBase & 0x00000700) >> 8;
          DramBase = DramBase & 0xFFFF0000;
          ...
          if(CSFound) break;
      }
      return(CSFound,NodeID,CS);
      }
    И простой вопрос: это же концептуальная запись (возврат нескольких значений)? Нет же такого ни в какой версии Си-компилятора?
    Снова простая попытка/схема реализовать столь нужный функционал! А то вечно приходится "костыли" городить, чтобы вернуть два-три значения... Эх... :'(
      Цитата Славян @
      И простой вопрос: это же концептуальная запись (возврат нескольких значений)? Нет же такого ни в какой версии Си-компилятора?

      Это С-подобный псевдокод. Смотрится нагляднее, чем возвращать структуру. Но это невалидный С-код.

      Цитата Славян @
      А то вечно приходится "костыли" городить, чтобы вернуть два-три значения... Эх...

      Да нет, структуры это решают красиво. Автор решил еще "приукрасить" :lol:
        В Плюсах есть, но синтаксис другой. Вроде того:
        ExpandedWrap disabled
          std::tuple<int, int, int> TranslateSysAddrToCS(uint32_t SystemAddr){
          /* ... */
          return { CSFound, NodeID, CS };
          }
           
          //
          int [found, node, cs] = TranslateSysAddrToCS(0x12345678u);
          Цитата Qraizer @
          В Плюсах есть, но синтаксис другой.

          Речь не о плюсах. В Си такое реализовать наиболее просто на структурах.
            Сперва сдержался, но всеж не могу - уж очень хочется поёрничать, очень! :D

            В далеком 2011 году в Стандарте С++ появилась киллер-фича "лямбды". Сколько себя помню в Perl, а это примерно 1997 год, там всегда это было.
            Никогда такого не было, и вот опять!!! Сколько себя помню в Perl, а это примерно 1997 год, там всегда была возможность возврата множественного результата. Для С ... бида-пичаль, а для C++ ... ешьте std::tuple в 2025 году! ;)
            Скрытый текст
            ExpandedWrap disabled
              #!/usr/local/bin/perl
               
              use strict;
              use warnings;
               
              my ($sign, $int, $frac) = SuperDiv(3,-2);
               
              print "$sign$int.$frac\n";
               
              sub SuperDiv {
                my ($dividend, $divisor) = @_;
                my $res = $dividend / $divisor;
                my $sign = ($res < 0) ? "-" : "";
                my $int = int(abs($res));
                my $frac = abs($res) - $int;
                $frac =~ s/^0\.//;
                return ($sign, $int, $frac);
              }

            ExpandedWrap disabled
              -1.5

            :victory:

            Это так, коротко о хороших и гениальных языках программирования!
              Цитата Majestio @
              В далеком 2011 году в Стандарте С++ появилась киллер-фича "лямбды". Сколько себя помню в Perl, а это примерно 1997 год, там всегда это было.

              В перл можно управлять захватом контекста лямбды? Можно определять, по значению, по ссылке или вообще перенести данные в лямбду? Вот и получается, что слово одно, а фичи разные :)

              Добавлено
              Цитата Majestio @
              Для С ... бида-пичаль, а для C++ ... ешьте std::tuple в 2025 году! ;)
              Скрытый текст
              ExpandedWrap disabled
                #!/usr/local/bin/perl
                 
                use strict;
                use warnings;
                 
                my ($sign, $int, $frac) = SuperDiv(3,-2);
                 
                print "$sign$int.$frac\n";
                 
                sub SuperDiv {
                  my ($dividend, $divisor) = @_;
                  my $res = $dividend / $divisor;
                  my $sign = ($res < 0) ? "-" : "";
                  my $int = int(abs($res));
                  my $frac = abs($res) - $int;
                  $frac =~ s/^0\.//;
                  return ($sign, $int, $frac);
                }

              ExpandedWrap disabled
                -1.5

              :victory:

              Это так, коротко о хороших и гениальных языках программирования!

              tuple тоже в 11 появился (хотя были потом изменения).
              Кстати, это класс стандартной библиотеки, а не часть самого языка. Т.е. возможности языка позволяют реализовать подобное не включая в сам язык.

              Добавлено
              Цитата Majestio @
              Никогда такого не было, и вот опять!!! Сколько себя помню в Perl, а это примерно 1997 год...

              Ну а чего perl? Чего там 97 год?
              Можно лисп вспомнить :lol:
                Цитата D_KEY @
                В перл можно управлять захватом контекста лямбды? Можно определять, по значению, по ссылке или вообще перенести данные в лямбду?


                По ссылке
                ExpandedWrap disabled
                  my $x = 10;
                  my $f = sub { return $x++ };
                  $f->(); # изменяет $x


                По значению
                ExpandedWrap disabled
                  my $x = 10;
                  my $f = do {
                      my $copy = $x;  # создаём локальную копию
                      sub { return $copy++ }
                  };
                  $f->(); # не изменяет $x


                Перенос
                ExpandedWrap disabled
                  my $x = 10;
                  my $f = do {
                      my $moved = $x;
                      undef $x;   # "обнуляем" внешнюю переменную
                      sub { return ++$moved }
                  };
                  $f->(); # переносит 10 в лямбду, а $x становится undef

                Цитата D_KEY @
                Вот и получается, что слово одно, а фичи разные

                :tong:
                  Цитата D_KEY @
                  tuple тоже в 11 появился (хотя были потом изменения).

                  Я знаю. Написал это к тому, что на дворе 2025 год, а до сих пор это неудобство.

                  Например в Dart тоже формально нельзя возвращать более одного значения, но там допустима конструкция:

                  ExpandedWrap disabled
                    (int, String) myfunc() {
                      return (42, "hello");
                    }
                     
                    void main() {
                      var (num, str) = myfunc(); // деструктуризация
                      print("$num, $str");
                    }

                  Функция myfunc по факту возвращает одно значение типа Record. Но посмотри как это красиво записано, и не нужно каких-либо библиотек. Без оверхеда лучше.
                    К вопросу об оверхеде
                    ExpandedWrap disabled
                      auto [found, node, cs] = TranslateSysAddrToCS(0x12345678u);
                    ExpandedWrap disabled
                              mov     edx, 305419896                          ; 12345678H
                              lea     rcx, QWORD PTR $S1$[rsp]                        ;<-
                              call    ?TranslateSysAddrToCS@@YA?AV?$tuple@HHH@std@@I@Z ; TranslateSysAddrToCS
                      ; Line 10
                              mov     r8d, DWORD PTR $S1$[rsp]                        ;<-
                              mov     edx, DWORD PTR $S1$[rsp+4]                      ;<-
                              mov     ecx, DWORD PTR $S1$[rsp+8]                      ;<-

                    ExpandedWrap disabled
                      std::tuple<int, int, int> TranslateSysAddrToCS(unsigned SystemAddr)
                      {
                        int CSFound = SystemAddr >> 16, NodeID = SystemAddr % (1 << 16), CS = SystemAddr != 0;
                      /* ... */
                        return { CSFound, NodeID, CS };
                      }
                    ExpandedWrap disabled
                              xor     eax, eax
                              movzx   r8d, dx
                              mov     r9d, edx
                      ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple
                      ; Line 158
                              mov     DWORD PTR [rcx+4], r8d                          ;<-
                      ; File D:\Work\DelMe\qq.cpp
                      ; Line 5
                              shr     r9d, 16
                              test    edx, edx
                      ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple
                      ; Line 158
                              mov     DWORD PTR [rcx+8], r9d                          ;<-
                      ; File D:\Work\DelMe\qq.cpp
                      ; Line 5
                              setne   al
                      ; File D:\VS2019\VC\Tools\MSVC\14.29.30133\include\tuple
                      ; Line 158
                              mov     DWORD PTR [rcx], eax                            ;<-
                      ; File D:\Work\DelMe\qq.cpp
                      ; Line 7
                              mov     rax, rcx
                      ; Line 8
                              ret     0
                    Можно на Dart посмотреть?
                    Сообщение отредактировано: Qraizer -
                      Цитата Qraizer @
                      Можно на Dart посмотреть?

                      Такое я еще не пробовал. Дело в том, что Dart сперва копилирует свой код в промежуточный, а уже потом тулчейнами в код целевой платформы. Я пока баловался только для Web - а там целевой код javascript. В принципе могу собрать exe для винды, но как там найти нужные места в ассемблерном представлении - я х3. Хэлоу ворлд будет порядка 20 метров. Хотя консольное приложение должно быть поменьше, т.к. хэлоу ворлд я делал на Dart+Flutter. А там статически влинковывается весь графический движок.

                      Добавлено
                      Хотя, о чем это я :) Для винды у Dart - формируется второе промежуточное представление на С++, и из него тулчейном уже собирается exe-шник. Поэтому имеет смысл просто смотреть сгенерированный С++ код. Будет время - проверю что там генерится.

                      Засада! Оказывается промежуточное представление на С++ делает не Dart, а Flutter для свои "обвязок". Код на Dart компилячится напрямую.

                      Добавлено
                      exe получается 5 мегов, а дизасемблирование 105 мегов ассемблерного кода. Ну его нафиг! :huh:
                      Сообщение отредактировано: Majestio -
                        А нет волшебного ключика "сделай asm"? Как у Студии -FA, например. Мож он тогда только своё сгенерит, без всякой либовой обвязки

                        Добавлено
                        Упс. В примерах кода прошмыгнуло чуток конфиденциальности. Подправил.
                          Цитата Qraizer @
                          А нет волшебного ключика "сделай asm"? Как у Студии -FA, например. Мож он тогда только своё сгенерит, без всякой либовой обвязки

                          Увы, нету. Я изучил вопрос. Сам Дарт сперва компилячит в свое внутренне представление, а потом из него в код целевой платформы. Есть отдельный ключ - он компилячит в объектный файл, но там сигнатура ELF, да и размер тоже сравнимый с exe. Максимум, что я могу сделать - представить кусок кода на js, но это всё совсем не то.
                          ExpandedWrap disabled
                              var A = {
                                printString(string) {
                                  if (typeof dartPrint == "function") {
                                    dartPrint(string);
                                    return;
                                  }
                                  if (typeof console == "object" && typeof console.log != "undefined") {
                                    console.log(string);
                                    return;
                                  }
                                  if (typeof print == "function") {
                                    print(string);
                                    return;
                                  }
                                  throw "Unable to print message: " + String(string);
                                },
                                _Universe_addRules(universe, rules) {
                                  return A._Utils_objectAssign(universe.tR, rules);
                                },
                                _Universe_addErasedTypes(universe, types) {
                                  return A._Utils_objectAssign(universe.eT, types);
                                },
                                _Utils_objectAssign(o, other) {
                                  var i, key,
                                    keys = Object.keys(other),
                                    $length = keys.length;
                                  for (i = 0; i < $length; ++i) {
                                    key = keys[i];
                                    o[key] = other[key];
                                  }
                                },
                                main() {
                                  A.printString("42, hello");
                                }
                              };
                            Цитата Majestio @
                            Есть отдельный ключ - он компилячит в объектный файл, но там сигнатура ELF, да и размер тоже сравнимый с exe

                            Скорми ELF в objdump
                              Цитата macomics @
                              Скорми ELF в objdump

                              Файлы прикрепил.
                              Прикреплённый файлПрикреплённый файлtest_intel.asm.7z (355,52 Кбайт, скачиваний: 10)
                              Прикреплённый файлПрикреплённый файлtest.aot.7z (221,94 Кбайт, скачиваний: 9)
                                Та фик там что найдёшь. Я даже myfunc не нашёл, а main аж две.

                                P.S. Кстати, за либы. От так тож можно, ибо структурное связывание языковое, а не либовое:
                                ExpandedWrap disabled
                                  struct { int i1; int i2; int i3; } TranslateSysAddrToCS(unsigned SystemAddr);
                                Сообщение отредактировано: Qraizer -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (81) « Первая ... 78 79 [80] 81 


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1274 ]   [ 18 queries used ]   [ Generated: 18.10.25, 03:50 GMT ]