Причуда структуры объекта MSVC

У меня есть простой класс в C++, который имеет целое число и vtable:

class Something {

   virtual void sampleVirtualMethod();

   int someInteger;
};

При рассмотрении структуры объекта для MSVC (использующий/d1reportSingleClassLayout), Вы добираетесь:

class Something       size(8):
        +---
 0      | {vfptr}
 4      | someInteger
        +---

Который имеет полный смысл. 4 байта для vtable указателя и 4 байта для целого числа. Странная вещь состоит в том, когда я добавляю вдвое большее по сравнению с классом:

class Something {    
    virtual void sampleVirtualMethod();
    int someInteger;
    **double someDouble;**
};

Я получаю эту структуру объекта:

class Something       size(24):
        +---
 0      | {vfptr}
 8      | someInteger
        | <alignment member> (size=4)
16      | someDouble
        +---

Почему различие между этими 0 смещениями и someInteger 8 вместо 4? vtable росло до 8 байтов так или иначе? Неважно, порядок того, когда я добавляю двойное, это происходит.

Спасибо.

6
задан Mason 15 February 2010 в 18:43
поделиться

2 ответа

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;

namespace Helpers
{
    internal class EmailHelper
    {
        public static string GetSenderEmailAddress(Microsoft.Office.Interop.Outlook.MailItem mapiObject)
        {
            Microsoft.Office.Interop.Outlook.PropertyAccessor oPA;
            string propName = "http://schemas.microsoft.com/mapi/proptag/0x0065001F";
            oPA = mapiObject.PropertyAccessor;
            string email = oPA.GetProperty(propName).ToString();
            return email;
        }
    }
}
-121--4349419-

Я подозреваю, что этот ответ имеет к нему отношение. Чтобы процитировать ответ dirkgently , процитируйте руководство GCC:

Обратите внимание, что выравнивание любого данного типа структуры или объединения требуется по стандарту ISO C, чтобы быть, по крайней мере, идеальным кратным наименьшему общему кратному выравниванию всех членов данной структуры или объединения.

Согласно этому правилу, после добавления 8-байтового двойника компилятор должен расположить все по 8-байтовым кратным числам. Вы можете переопределить это с # pragma pack (), конечно, хотя это будет менее эффективно, если вы окажетесь с 8-байтовым членом на чем-то, кроме 8-байтовой границы.

1
ответ дан 17 December 2019 в 18:15
поделиться

Я не могу ответить на ваш вопрос напрямую, потому что нет веского оправдания поведению компилятора. Вместо этого я позволю себе дикие спекуляции, так как еще не было ответа.

Я подозреваю ошибку в алгоритме выравнивания, которая выглядит примерно так :

  • выравнивание структуры (т. Е. Размещение первого члена) должно быть по крайней мере таким же широким, как выравнивание ее самого широкого члена
  • ой, забыл считать указатель таблицы виртуальной функции как член

Если это есть ошибка. Я подозреваю, что она осталась от ранних дней компилятора как компилятор C с 4-байтовым выравниванием. Теперь по умолчанию для компилятора используется / Zp8 , что означает, что каждая структура выровнена как минимум по 8 байтам, так что в любом случае нет необходимости исправлять выравнивание "первого" члена.

С уважением, Шерм

0
ответ дан 17 December 2019 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: