2016-09-01 4 views
2

Учитывая, что существуют некоторые несвязанные флаги (sta_scan, search), которые определены как битовые поля в структуре, как показано ниже. Определяется ли место, где эти флаги объявлены (с точки зрения сохранения памяти)?расположение битовых полей в структуре

struct sta_all { 
    char name[16]; 
    unsigned int sta_scan:1; 
    ... 
    int interval; 
    unsigned int search:1; 
} 
+2

Каждое из этих битовых полей, вероятно, будет выделено так много места, как базовый тип ('unsigned int') и будет использовать 1 из 32 (16, 64, ...) бит в этом блоке хранения. Если вы решили использовать бит-поля, вы должны убедиться, что все битовые поля сгруппированы вместе; это минимизирует пространство впустую. Вы должны подумать о том, будет ли использоваться 'bool' (от' 'или' _Bool') ваши цели, или лучше. Множество деталей о битовых полях определяется реализацией, но в контексте структуры компилятор не имеет права перемещать битподы вокруг. –

+0

компиляторам не разрешено [переупорядочить элементы структуры] (http://stackoverflow.com/q/9486364/995714), поэтому вам нужно сделать это самостоятельно, если вы не включили некоторые [параметры компилятора] (http://stackoverflow.com/q/14671253/995714) –

+0

artM хороший вопрос, я редактирую свой ответ, так как вчера, вместо того, чтобы считать овец в моей постели, я подсчитывал бит, надеюсь, что вы найдете это полезным! :) – gsamaras

ответ

3

Да, но не всегда.


Проверить этот пример:

#include <stdio.h> 
#include <string.h> 

struct { 
    char name[16]; 
    unsigned int sta_scan:1; 
    int interval; 
    unsigned int search:1; 
} sta_all; 

int main() { 

    sta_all.interval = 4; 
    printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all)); 

    return 0; 
} 

Выход:

Sizeof (sta_all): 28

и:

#include <stdio.h> 
#include <string.h> 

struct { 
    char name[16]; 
    unsigned int sta_scan:1; 
    unsigned int search:1; 
    int interval; 
} sta_all; 

int main() { 

    sta_all.interval = 4; 
    printf("Sizeof(sta_all) : %zu\n", sizeof(sta_all)); 

    return 0; 
} 

Выход:

Sizeof (sta_all): 24

Это происходит из-за обивка, on my platform.

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

Примечание: В приведенном выше примере подтверждает то, что Jonathan Leffler упоминалось в этом comment:

Каждый из этих битовых полей, вероятно, будет выделено столько места, сколько базового типа (unsigned int) и будет использовать 1 из 32 (16, 64, ...) в этом блоке хранения. Если вы решили использовать бит-поля, вы должны убедиться, что все битовые поля сгруппированы вместе; это минимизирует пространство впустую. [...]. В контексте структуры компилятор не имеет права перемещать битподы вокруг.

..which приходит к совершенной гармонии с связанного ответа, так как компилятор должен добавить меньше char gap_{i}[3];, когда мы группироваться битовые поля, тем самым уменьшая размер структу!


Стоило ли?

Не так много ИМХО ...:)

+0

Почему вы положили огромные поля, которые OP не должны делать, чтобы относительная разница казалась искусственно малой? –

+0

@R .. только для удовольствия. Но поведение не изменится, конечно. Проверьте мое обновление, вам нравится мой ответ сейчас? :) – gsamaras

+1

Мне бы хотелось, чтобы это было лучше, если бы было 24 против 28 (не добавлялось никаких глупых поплавков). –

1

В общем, да. Элементы Struct обычно выравниваются каким-либо образом (как правило, с размером элемента, иногда чем-то большим), и смешивание различных размеров может привести к большому количеству дополнений. Есть способы смягчить это. В общем, если вы объедините все элементы одного размера вместе, они, вероятно, будут упакованы без каких-либо дополнений. Можно использовать прагмы, чтобы заставить структуру быть упакованной без заполнения, но тогда это приведет к неэффективным негласным обращениям к членам структуры.

+1

Вы не можете заставить no-padding на битполе. –

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