2013-03-11 4 views
2

Я хочу создать союз с struct и и uint64_t, поэтому я могу ссылаться на отдельные uint16_ts на struct и объединить их в uint64_t. Я сделал эту тестовую программу:порядок памяти structs и ints

#include "stdio.h" 
#include "stdint.h" 
struct test_struct{ 
    uint16_t stuff; 
    uint16_t a; 
    uint16_t b; 
    uint16_t c; 
}; 

union test_union{ 
    struct test_struct str; 
    uint64_t uint; 
};  

int main(){ 
    struct test_struct x = { 
     .stuff = 0x0000, 
     .a = 0x1234, 
     .b = 0x5678, 
     .c = 0x9ABC 
    }; 
    union test_union y; 
    y.str = x; 

    printf("y.uint: %llX\n", y.uint); 
} 

Выходной сигнал становится:

y.uint: 9ABC567812340000 

, который является нелогичным для меня (это будет Шоуда 000ABC или 123456789ABC). Может кто-нибудь объяснить мне, почему элементы в структуре кажутся обратными?

EDIT: Для справок в будущем: ответы на вопросы, принятые на континент, меня смутили, потому что uint16_ts были напечатаны в правильном порядке. Но это, конечно, потому, что они сами хранятся малоподобными.

ответ

7

Вы находитесь на платформе little-endian, а первые байт (с наименьшими адресами) заканчиваются наименее значимыми битами (правая сторона при печати) объединенного uint64_t.

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

0

Это связано с Endianess. Я не думаю, что язык C/C++ определяет способ, которым это работает, оставляя его для ЦП реализации/цели, чтобы определить. На большом процессоре вы бы получили то, что ожидали.

0

Если ваш процессор является «малозначим», LSB хранится на самом нижнем адресе, так что это нормальный выход. На платформе Intel x86, как правило, она малозначительная. Напротив, PowerPC от Motorola - это big-endian, то есть MSB, хранящийся на самом низком адресе.

Смежные вопросы