Обновить
0

Пользователь

1
Подписчики
Отправить сообщение
Я вот тоже знаком с автором лично и специально уточнил у него: «Сатирой это назвать сложно.»
Антипример — С++. Впоследствии разработчики языков стали учитывать ошибки С++, и например C# гораздо лучше парсится «на лету».

Проблема парсинга C++ не столько в том, что его парсить долго, сколько в том, что его парсить много:
$ cat hw.cpp
#include <iostream>
int main() { std::cout << "Hello, World!\n"; }

$ g++ -std=c++11 -E hw.cpp | wc
  24304   53850  597619
Там, где другие распарсили бы 2 строчки, компилятор C++ парсит почти 0.6 Мб.
Для простого случая gcc выдаёт практически идентичный код.
#include <boost/range/irange.hpp>

void do_the_thing(int);

void oldschool(int a, int b)
{
    for (auto i = a; i < b; ++i)
        do_the_thing(i);
}

void ranges(int a, int b)
{
    for (auto i : boost::irange(a, b))
        do_the_thing(i);
}

$ g++-4.9.2 -std=c++14 -O3 -DNDEBUG -c range.cpp

$ objdump -dC range.o 
range.o:     формат файла elf64-x86-64


Дизассемблирование раздела .text:

0000000000000000 <oldschool(int, int)>:
   0:   55                      push   %rbp
   1:   53                      push   %rbx
   2:   89 f5                   mov    %esi,%ebp
   4:   89 fb                   mov    %edi,%ebx
   6:   48 83 ec 08             sub    $0x8,%rsp
   a:   39 f7                   cmp    %esi,%edi
   c:   7d 10                   jge    1e <oldschool(int, int)+0x1e>
   e:   66 90                   xchg   %ax,%ax
  10:   89 df                   mov    %ebx,%edi
  12:   83 c3 01                add    $0x1,%ebx
  15:   e8 00 00 00 00          callq  1a <oldschool(int, int)+0x1a>
  1a:   39 eb                   cmp    %ebp,%ebx
  1c:   75 f2                   jne    10 <oldschool(int, int)+0x10>
  1e:   48 83 c4 08             add    $0x8,%rsp
  22:   5b                      pop    %rbx
  23:   5d                      pop    %rbp
  24:   c3                      retq   
  25:   66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  2c:   00 00 00 00 

0000000000000030 <ranges(int, int)>:
  30:   55                      push   %rbp
  31:   53                      push   %rbx
  32:   89 f5                   mov    %esi,%ebp
  34:   89 fb                   mov    %edi,%ebx
  36:   48 83 ec 08             sub    $0x8,%rsp
  3a:   39 f7                   cmp    %esi,%edi
  3c:   74 10                   je     4e <ranges(int, int)+0x1e>
  3e:   66 90                   xchg   %ax,%ax
  40:   89 df                   mov    %ebx,%edi
  42:   83 c3 01                add    $0x1,%ebx
  45:   e8 00 00 00 00          callq  4a <ranges(int, int)+0x1a>
  4a:   39 dd                   cmp    %ebx,%ebp
  4c:   75 f2                   jne    40 <ranges(int, int)+0x10>
  4e:   48 83 c4 08             add    $0x8,%rsp
  52:   5b                      pop    %rbx
  53:   5d                      pop    %rbp
  54:   c3                      retq   


Насчет сложных случаев не уверен, можно ли сочинить такой, что gcc решит это всё не инлайнить.
Перечитал статью внимательнее. Судя по симптомам и лечению, действительно (был) единственный.

ISO IEC 14882-2003 §12.8 Copying class objects [class.copy]
A member function template is never instantiated to perform the copy of a class object to an object of its class type.

Сноска:
106) Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.


ISO IEC 14882-2011 §12.8 Copying class objects [class.copy]
A member function template is never instantiated to produce such a constructor signature.


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

Т.е. нужно явно определять конструктор копирования, что вы в итоге и сделали, но это не «some magic cases», а так и задумано.

А copy-elision тут ни в чём не виновен.
    template<typename T_OtherType,
            typename T_OtherHolding,
            typename T_OtherAccess>
    DReference(
            const DReference<T_OtherType, T_OtherHolding, T_OtherAccess> &
                    inLReference) : _holder(NULL), _holding(), _access()
    {
        retain(inLReference._holder);
    }


Это единственный конструктор, предназначеный для копирования DReference?
Вписывается:

svn.boost.org/trac/boost/wiki/BoostEvo

However, it is ultimately the decision of the library developer which versions of C++ to support and how.

New libraries will not be rejected because they lack support for older platforms, particularly if new language or library features are integral to the library interface or design. An example would be a library that cannot provide a usable interface without use of a new C++ feature.

GCC 4.5.3
B::B()
B::B(const B&)
B::B(const B&)
B::~B()
B::~B()
B::~B()

GCC 4.6.3
B::B()
B::B(const B&)
B::B(B&&)
B::~B()
B::~B()
B::~B()

GCC 4.7.2
B::B()
B::B(const B&)
B::B(B&&)
B::~B()
B::~B()
B::~B()

Про precompiled headers + cmake можно посмотреть тут: www.cmake.org/Bug/view.php?id=1260.
http://www.artima.com/cppsource/type_erasure.html?

Также можно взглянуть на Boost.TypeErasure, который недавно приняли в состав.

Ещё на эту тему есть тут: http://www.youtube.com/watch?v=_BpMYeUFXv8.
BitSpyder, пожалуйста.
Т.е. %home% вместо $HOME или ~ вас не смущает?
Это смотря как считать :)
Тут автор излагает эту идею на чуть более конкретных вещах: http://www.youtube.com/watch?v=WpkDN78P884.
Добавил в тест BOOST_FOREACH.

Linux 32bit, gcc 4.6.3, Qt 4.8.1

"New for" results(ms): avg:100 min:97 max:108
"Accumulate" results(ms): avg:100 min:97 max:108
"Qt foreach" results(ms): avg:103 min:100 max:112
"Boost foreach" results(ms): avg:101 min:97 max:106
"STL for" results(ms): avg:130 min:126 max:151
"STL for 2" results(ms): avg:99 min:97 max:104

Run test for type: FSt6vectorIiSaIiEEvE
"New for" results(ms): avg:100 min:97 max:106
"Accumulate" results(ms): avg:98 min:95 max:104
"Qt foreach" results(ms): avg:258 min:249 max:290
"Boost foreach" results(ms): avg:100 min:97 max:107
"STL for" results(ms): avg:100 min:98 max:107
"STL for 2" results(ms): avg:99 min:97 max:108

Run test for type: F5QListIiEvE
"New for" results(ms): avg:100 min:98 max:110
"Accumulate" results(ms): avg:101 min:98 max:106
"Qt foreach" results(ms): avg:103 min:101 max:111
"Boost foreach" results(ms): avg:100 min:98 max:108
"STL for" results(ms): avg:131 min:126 max:146
"STL for 2" results(ms): avg:101 min:98 max:110
*посмотреть его
Тогда уж лучше increaseSpeed(double speed_meters_per_sec), ато ещё спросят как вы в миллисекундах скорость измеряете.

А вообще идея статьи взята из выступления Страуструпа на GoingNative2012 (но примеры и реализация как-то неудачно обрезаны), лучше посмотреть, если ещё не.
Он(майнкрафт) как чистый лист бумаги: если тебе есть что сказать — ты пишешь, если же нет, то сам по себе этот лист бумаги тебя не развеселит, в этом наверное и заключается главный минус данной игры.
© откуда-то из интернета
Хм. Заметил сейчас у вас там слово «надеюсь». Приношу свои извинения за несдержанный тон высказываний. Можно сказать больная для меня тема.
А вот насчет в голову не придет… там одной светлой голове уже пришло в одном канале с сигнальным кабелем провести силовой.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность