На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (11) « Первая ... 2 3 [4] 5 6 ...  10 11 все  ( Перейти к последнему сообщению )  
> Баллада о ссылках в С++
    Вот что рожает gcc 7.1 -O3 для
    ExpandedWrap disabled
      printf("%p", c);

    ExpandedWrap disabled
      .LC0:
              .string "%d"
      .LC1:
              .string "%p"
      Refs1():
              sub     rsp, 24
              mov     edi, OFFSET FLAT:.LC0
              xor     eax, eax
              mov     DWORD PTR [rsp+12], 10
              mov     esi, DWORD PTR [rsp+12]
              call    printf
              mov     esi, DWORD PTR [rsp+12]
              mov     edi, OFFSET FLAT:.LC0
              xor     eax, eax
              call    printf
              lea     rsi, [rsp+16]
              mov     edi, OFFSET FLAT:.LC1
              xor     eax, eax
              call    printf
              add     rsp, 24
              ret

    Меняем на
    ExpandedWrap disabled
      printf("%p", *c);

    И видим, что изменилась ровно одна строка, что в общем то и ожидалось:
    ExpandedWrap disabled
      .LC0:
              .string "%d"
      .LC1:
              .string "%p"
      Refs1():
              sub     rsp, 24
              mov     edi, OFFSET FLAT:.LC0
              xor     eax, eax
              mov     DWORD PTR [rsp+12], 10
              mov     esi, DWORD PTR [rsp+12]
              call    printf
              mov     esi, DWORD PTR [rsp+12]
              mov     edi, OFFSET FLAT:.LC0
              xor     eax, eax
              call    printf
              mov     esi, DWORD PTR [rsp+16]   ;было lea rsi, [rsp+16]
              mov     edi, OFFSET FLAT:.LC1
              xor     eax, eax
              call    printf
              add     rsp, 24
              ret

    И что я тут должен увидеть? GCC создал одну переменную a на стеке, после чего соптимизировал в пустоту и ссылку и указатель и лезет и за тем и за другим напрямую туда где лежит a.

    Это сообщение было перенесено сюда или объединено из темы "D vs C++"
    Сообщение отредактировано: applegame -
      applegame, ты должен там увидеть (и увидишь) что указатель есть (rsp+16), а ссылки - нет.... При обращении по ссылке он лезет в переменную (rsp+12).

      Это сообщение было перенесено сюда или объединено из темы "D vs C++"
        Что-то вы в реализацию ушли.

        Это сообщение было перенесено сюда или объединено из темы "D vs C++"
          Цитата Flex Ferrum @
          applegame, ты должен там увидеть (и увидишь) что указатель есть (rsp+16), а ссылки - нет.... При обращении по ссылке он лезет в переменную (rsp+12).
          Ты ошибаешься.
          (rsp + 16) - это не указатель, это адрес переменной a плюс единица: (rsp + 12 + sizeof(int)) == rsp+16
          Замени "&b + 1" на "&b + 2" и (rsp+16) поменяется на (rsp+20): https://godbolt.org/g/j39jBP
          Там только одна переменная - (rsp+12). Для указателя и ссылки GCC не выделил память.

          На самом деле на сайте это и так видно. Строки с объявлением указателя и ссылки имеют белый цвет, а это значит, что для них не сгенерировано никакого кода. Они соптимизированы полностью.

          Добавлено
          Цитата D_KEY @
          Что-то вы в реализацию ушли.
          Это потому что Флекс почему-то уверен, что в реализации ссылок и указателей есть какая-то принципиальная разница. Хотя это уже второй пример, когда выделение памяти под указатель не происходит.
          То есть, вот это утверждение уже дважды опровергнуто, даже volatile не помогает:
          Цитата Flex Ferrum @
          Как раз таки под указатель память будет выделена всегда. И это отличие - фундаментальное.


          Это сообщение было перенесено сюда или объединено из темы "D vs C++"
          Сообщение отредактировано: applegame -
            Да это вопрос оптимизации и кодогенерации. Меня же волнует система типов. Я пока не вижу толк от того, что ссылки это часть именно системы типов.

            Это сообщение было перенесено сюда или объединено из темы "D vs C++"
              Цитата applegame @
              Это потому что Флекс почему-то уверен, что в реализации ссылок и указателей есть какая-то принципиальная разница.

              Угу. Есть.

              Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                Цитата Flex Ferrum @
                Угу. Есть.
                Нет, нету. Тут у тебя ссылка и указатель в неравных условиях. Волатильную ссылку создать нельзя в отличие от указателя. В итоге ты просто, грубо говоря, запертил оптимизировать указатель, а ссылку не запретил. Отключи оптимизацию вообще и для ссылки тоже будет выделена память.
                А так я могу легко заставить выделить память под твою ссылку даже с оптимизацией: https://godbolt.org/g/sNgSPX

                Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                Сообщение отредактировано: applegame -
                  Цитата applegame @
                  Волатильную ссылку создать нельзя в отличие от указателя. В итоге ты просто, грубо говоря, запертил оптимизировать указатель, а ссылку не запретил.

                  Что и требовалось доказать. :) Указатель волатильным сделать можно. А вот ссылку - уже нет. Это разные сущности, с разной семантикой. Хоть и похожие в чём-то. :)

                  Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                    Цитата applegame @
                    Волатильную ссылку создать нельзя в отличие от указателя

                    и указатель на ссылку нельзя, а ссылку на указатель можно.
                    значит, таки есть отличия?! :-? и да, хватит тут чирикать, ответьте на мой вопрос, гуру D :)

                    Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                      Цитата Flex Ferrum @
                      Что и требовалось доказать. :) Указатель волатильным сделать можно. А вот ссылку - уже нет. Это разные сущности, с разной семантикой. Хоть и похожие в чём-то. :)
                      А это и не требовалось доказать. Очевидно, что ссылки - это не указатели. Но область применения ссылок полностью перекрывается указателями. То бишь без ссылок обойтись можно, а вот без указателей уже нет. Можно сказать, что ссылки - это эдакие сильно ограниченные указатели с автоматическим разыменованием. Если ты сам себе запретишь делать с указателями то, что запрещено делать со ссылками, то разница между ними исчезнет (кроме синтаксиса).
                      А вообще мы говорим об одном и том же, но с разных сторон. С точки зрения реализации можно сказать, что ссылка - это указатель, с логической же точки зрения это не указатель, а алиас. Но для чистоты алиаса не хватает запрета на фокусы, вроде ссылок на объекты из кучи.
                      Цитата _lcf_ @
                      и да, хватит тут чирикать, ответьте на мой вопрос, гуру D :)

                      Если ты про это
                      Цитата _lcf_ @
                      а если в качестве возвращаемого значения - какой-нибудь нуль(птр/опт/ещекакаянибудьбдня) можно вернуть, или только указатель на объект, который кажет в нульптр?
                      То я не понял вопроса. Объясни нормальным птичьим языком. :)
                      Типа если функция возвращает ссылку, то можно ли вернуть ссылку содержащую null?

                      Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                      Сообщение отредактировано: applegame -
                        Цитата applegame @
                        Объясни нормальным птичьим языком.

                        ну что-то типа такого:
                        ExpandedWrap disabled
                          some_class *class_normal;
                          some_class *class_int;
                          some_class *class_log;
                          some_class *class_empty = nullptr;
                          ...
                          some_class *&foobar::get_class_for_mode(some_class_enum_mode mode)
                          {
                            switch (mode) {
                              case some_class_enum_mode::NORMAL:
                                return class_normal;
                                break;
                              case some_class_enum_mode::INTEGER:
                                return class_int;
                                break;
                              case some_class_enum_mode::LOGARITHMIC:
                                return class_log;
                                break;
                              case some_class_enum_mode::UNDEFINED:
                              case some_class_enum_mode::COUNT:
                                break;
                              }
                           
                            return class_empty; //TODO mmm, not good idea?!
                          }


                        ну если про использование, то дальше что-то типа:

                        ExpandedWrap disabled
                          for (auto t : enum_range (some_class_enum_mode::COUNT))
                              {
                                some_class *&sc = get_class_for_mode (some_class_enum_mode(t));
                                if (sc)
                                  {
                                    //TODO do something with sc
                                  }
                              }


                        Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                          Цитата _lcf_ @
                          ну что-то типа такого:
                          Так сделать можно, да.
                          Цитата _lcf_ @
                          ну если про использование, то дальше что-то типа:
                          А вот так нет. В D нельзя создать переменную-ссылку. Нужно использовать указатель. И кстати в твоем случае ссылка выступает уже не как алиас а как просто разыменованный указатель.

                          Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                            хм, ну ладно. я думал, вдруг вот это:
                            ExpandedWrap disabled
                              return class_empty; //TODO mmm, not good idea?!

                            можно заменить каким-нибудь
                            ExpandedWrap disabled
                              return null[ptr|opt|magic];

                            :)

                            Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                              Цитата applegame @
                              Но область применения ссылок полностью перекрывается указателями. То бишь без ссылок обойтись можно, а вот без указателей уже нет.

                              Да ну? :D Ну, вот тебе пример кода:
                              ExpandedWrap disabled
                                std::string HelloWorld()
                                {
                                    std::string hw = "Hello World!";
                                    return hw;
                                }
                                 
                                auto TakingPtr(std::string* str)
                                {
                                    return *str;
                                }
                                 
                                auto TakingRef(const std::string& str)
                                {
                                    return str;
                                }
                                 
                                int main()
                                {
                                    std::string* hw0 = &HelloWorld();
                                    const std::string& hw = HelloWorld();
                                    auto hw1 = TakingPtr(&std::string("Hello World!"));
                                    auto hw2 = TakingRef(std::string("Hello World!"));
                                    std::cout << *hw0 << std::endl;
                                    std::cout << hw << std::endl;
                                    std::cout << hw1 << std::endl;
                                    std::cout << hw2 << std::endl;
                                }

                              Без привлечения компилятора скажи - что будет выведено на экран? А потом возьми компилятор и проверь.

                              Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                                Цитата _lcf_ @
                                можно заменить каким-нибудь
                                А что мешает просто вернуть указатель на класс? А в качестве пустого значения null? Зачем эта странная движуха со ссылками?

                                Это сообщение было перенесено сюда или объединено из темы "D vs C++"
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (11) « Первая ... 2 3 [4] 5 6 ...  10 11 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0640 ]   [ 15 queries used ]   [ Generated: 27.04.24, 08:13 GMT ]