Как исправить предупреждение компиляции gcc в C ++ для заполнения структуры - PullRequest
0 голосов
/ 27 августа 2018

У меня есть следующий безобидно выглядящий код:

void myFunc(){
    struct stance {
        long double interval;
        QString name;
    };
    // [...]
}

Когда я собираю его, используя стандартную версию gcc в Ubuntu 18.04, я получаю следующее предупреждение:

MySource.cpp: 12: предупреждение: размер заполнения 'stance' с 8 байтами к границе выравнивания (-wpadded)

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

Однако я пытаюсь получить сборку без предупреждений, и поэтому возникает вопрос, как я могусделать это явным образом в моем коде стандартным образом, чтобы компилятору не выдавалось это предупреждение?

Итак, чтобы было ясно, я не хочу подавлять предупреждения в моем сценарии сборки, ни с использованием #pragma или аналогичных либо.Я хочу изменить код этой структуры так, чтобы мои ожидания выравнивания были явными и соответствовали тому, что хочет сделать компилятор, поэтому не нужно отображать предупреждение.

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Просто отключите предупреждение (или - ну, не включайте его, я не знаю ни одного набора предупреждений, такого как -Wall или -Wextra, который включает его).-Wpadded не всегда должен быть включен, если вы не хотите всегда вручную указывать необходимые отступы.

-Wpadded

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

(выделение добавлено)

Это один случай, когда это невозможно.long double равен 10 байтам и требует выравнивания 16 байт (4 в x86 Linux);QString фактически является указателем, поэтому ему требуется выравнивание 8 байтов (4 в 32-битной Linux).Вы можете поменять их местами так, как хотите, но если вы хотите сохранить естественное выравнивание (и, следовательно, наилучшую производительность), вы получите либо 6 + 8 байт заполнения, либо 8 + 6 байт заполнения.

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

Как упомянуто выше, единственная альтернатива (сохранение хорошего выравнивания) - сделать заполнение явным, но это не имеет особого смысла (если вы не разрабатываете формат файла или что-то и не хотите сделать все явным,но в этом случае вы бы не использовали QString и упаковали бы в 1 байт).

struct stance {
    long double interval;
    char unused0[6];
    QString name;
    char unused1[8];
};
0 голосов
/ 27 августа 2018

Я хочу изменить код этой структуры так, чтобы мои ожидания выравнивания были явными

Похоже, вы хотите использовать оператор alignof и использовать егос alignas спецификатором .Так что вам нужен по крайней мере C ++ 11, и вы можете захотеть std::alignment_of

...