Накладные расходы классов D

Я думал, что слышал, что классы D имеют два слова (2 void*) служебных данных вместо одного слова, требуемого C++. Я также слышал, что макет vtable несовместим с C++. Я правильно помню? Если да, то чем обоснованы эти решения?


person Qwertie    schedule 28.07.2012    source источник
comment
Не нужно, чтобы это было слышно — источник есть, иди и посмотри сам. :)   -  person DejanLekic    schedule 29.07.2012
comment
Если вам нравится клонировать репозитории git и часами ломать голову над более чем 100 000 строк исходного кода в надежде найти ответ на простой вопрос, конечно. Что касается меня, я просто спрошу, если кто-то уже знает ответ :)   -  person Qwertie    schedule 22.08.2012


Ответы (2)


Несколько вещей:

  1. В C++ класс без виртуальных функций будет иметь нулевые накладные расходы.
  2. В D класс всегда наследует виртуальные функции от Object, поэтому он всегда имеет накладные расходы __vptr, но также имеет __monitor, которого нет у объектов класса C++.
  3. Как в C++, так и в D будут дополнительные vptr для каждого интерфейса, который реализует класс.

Макет vtable несовместим с C++, потому что D включает указатель на экземпляр TypeInfo, который имеет информацию о типе времени выполнения для класса. С++, очевидно, не имеет этого, поэтому он несовместим.

person Peter Alexander    schedule 29.07.2012
comment
Стоит отметить, что вы можете использовать extern(C++) для создания совместимой виртуальной таблицы. Вероятно, также следует сказать, что структуры в D можно использовать, когда не требуются накладные расходы. - person jA_cOp; 29.07.2012
comment
Что ж, я очень надеюсь, что разработчики D изменят эту реализацию. Зачем несинхронизированным классам иметь __monitor? Кроме того, хотя классы C++ не будут иметь этой штуки TypeInfo, это не должно препятствовать тому, чтобы C++ вызывал виртуальные функции D и наоборот: просто поместите TypeInfo в vptr[-1], где он не мешает. Ходили разговоры об исключении opCmp, opEqual и т. д. из Object; надеюсь, они рассмотрят возможность добавления двоичной совместимости с C++ примерно в то же время, по крайней мере, для простых случаев. (Да, есть extern(C++), но в чем недостаток совместимости по умолчанию?) - person Qwertie; 29.07.2012
comment
По сути, если вы рассылаете объекты в количестве, достаточном для того, чтобы четыре байта имели значение, что-то в вашем дизайне сломано. D имеет структуру для типов POD. Кроме того: разве С++ сам по себе не является достаточным уроком недостатков обратной совместимости? - person FeepingCreature; 02.08.2012
comment
Должен согласиться с @FeepingCreature, если эти 4 или 8 байтов действительно имеют значение, то вы, вероятно, создаете слишком много экземпляров класса для начала. Воспользуйтесь преимуществами массовой эффективности и объедините несколько экземпляров в один. - person Peter Alexander; 02.08.2012

Дополнительный указатель относится к объекту монитора для синхронизированных классов (очевидно, были разговоры об его удалении для несинхронизированных классов, но этого не произошло). Макет задокументирован в разделе ABI спецификации.

Я не уверен, чем макет vtable отличается от того, как это делают компиляторы C++. Кто-то другой, вероятно, может ответить на это.

person eco    schedule 28.07.2012
comment
Просто чтобы уточнить, вы можете получить объекты с нулевыми накладными расходами без виртуальных функций в D, используя структуры и используя alias this для имитации наследования. - person dsimcha; 29.07.2012