Инициализировать структуру внутри объединения (C ++) - PullRequest
1 голос
/ 21 октября 2011

Я создаю очень ограниченный, специфичный для домена ассемблер x86 в C ++ (Visual Studio 2010), который динамически генерирует инструкции, записывает их в память и выполняет их все во время выполнения. Сначала я записываю их во временный поток байтов, а затем записываю весь поток в исполняемую память за один memcpy.

Я использую следующий код для построения movsd [imm32], xmm1 инструкции:

typedef unsigned char byte;
enum SSE2Register;

void WriteValueToMemory(double* dest, SSE2Register source)
{
    union
    {
        struct
        {
            byte insts[4];
            double* dest;
        };

        byte bytes[8];
    } movsd = 
    {
        // movsd [imm32], xmm1
        0xF2, 0x0F, 0x11, // Opcode
        0x05 + (8 * source), // ModR/M 
        dest // imm32
    };

    _stream.Write(movsd.bytes, sizeof(movsd.bytes));
}

Этот код работает: три байта кода операции и байт ModR / M записываются в insts, пункт назначения (imm32) записывается в dest, а bytes содержит всю инструкцию в необработанных байтах, готов к записи в поток инструкций.

Однако мне любопытно, является ли этот метод инициализации объединения безопасным / переносимым. Можно ли инициализировать четыре значения insts и значение dest в пределах одного набора скобок?

Другими словами, это правильный, переносимый способ сделать это, или я должен сделать это по-другому?

Спасибо!

1 Ответ

2 голосов
/ 21 октября 2011

http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx

Анонимные структуры

Расширение Microsoft C позволяет объявлять структурную переменную в другой структуре без указания имени.Эти вложенные структуры называются анонимными структурами.C ++ не позволяет анонимные структуры.

Вы можете получить доступ к членам анонимной структуры, как если бы они были членами в содержащей структуре.1014 * за то, что ты делаешь.

void WriteValueToMemory(double* dest, SSE2Register source)
{
    struct
    {
        byte insts[4];
        double* dest;
    } movsd = 
    {  // movsd [imm32], xmm1
        0xF2, 0x0F, 0x11, // Opcode
        0x05 + (8 * source), // ModR/M 
        dest // imm32
    };

    _stream.Write(&movsd, sizeof(movsd));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...