LINUX.ORG.RU

предупреждение: атрибут ‘packed’ для поля типа ‘unsigned char’ проигнорирован


0

0

Имеется такой кусок программы на си:

        struct REGS_BLOCK
        {
                unsigned char P __attribute__ ((packed)),
                              A __attribute__ ((packed)),
                              Y __attribute__ ((packed)),
                              X __attribute__ ((packed)),
                              S __attribute__ ((packed)),
                              PCh __attribute__ ((packed)),
                              PCl __attribute__ ((packed));
        } Snap;
Когда GCC 4.3 его компилирует, выдаёт предупреждения:
предупреждение: атрибут ‘packed’ для поля типа ‘unsigned char’ проигнорирован

Возникло 3 вопроса:

1. Как по-вашему, что имел в виду автор программы? Чтобы все эти 1-байтные переменные шли подряд, без зазоров?

2. Правильно ли будет заменить этот фрагмент на

struct REGS_BLOCK
{
unsigned char P, A, Y, X, S, PCh, PCl;
} Snap __attribute__ ((packed);
?

3. Во всех ли компиляторах будут правильно работать 1-й и 2-ой варианты?

★★★★★

1. этот атрибут для структуры, потому не понятно, что он хотел
2. да
3. нет, если надо совместимость с visual - есть #pragma pack

lester ★★★★
()
Ответ на: комментарий от lester

> 1. этот атрибут для структуры, потому не понятно, что он хотел

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

2. да

Спасибо.

3. нет, если надо совместимость с visual - есть #pragma pack

Спасибо, а как насчёт старых версий GCC, в районе 2.0?

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

> Не могло ли это в каких-то версиях GCC приводить к тому

а как насчёт старых версий GCC, в районе 2.0?


я 2.0 в глаза не видел - только начиная с 2.95 :) но насколько я знаю этот атрибут всегда относился именно к структурам, а не их полям, которые не представляют из себя структуру, по крайней мере в 3.х/4.х так и есть

2. да


и да, сначала не заметил - этот атрибут надо добавлять перед Snap, а не после

lester ★★★★
()

Имеется такой кусок программы на си:

этот кусок некорректен, и не правильно логически написан.
Видно человек который его писал, не знал для чего нужен атрибут ((packed))

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от lester

> этот атрибут надо добавлять перед Snap, а не после

Спасибо, напутал.

насколько я знаю этот атрибут всегда относился именно к структурам, а не их полям

Поэкспериментировал. Если этот атрибута ставить к полям short, int и long, GCC 4.3 не ругается. И отключает их выравнивание.

question4 ★★★★★
() автор топика
Ответ на: комментарий от Boy_from_Jungle

> человек который его писал, не знал для чего нужен атрибут ((packed))

Так для чего? Чтобы компилятор не добавлял пустого пространства вокруг многобайтных полей, не являющихся массивами?

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

> Поэкспериментировал. Если этот атрибута ставить к полям short, int и long, GCC 4.3 не ругается. И отключает их выравнивание

да - я был не прав, __attribute__ ((packed)) после объявления структуры просто применяет этот атрибут ко всем ее полям - «Specifying this attribute for struct and union types is equivalent to specifying the packed attribute on each of the structure or union members.», так что можно смело вынести его в вашем примере за '}'

П.С. я балбес - всегда надо читать документацию до конца :)

lester ★★★★
()
Ответ на: комментарий от md5xxx1

видимо автор писал просто для всех полей этот аттрибут, и старая версия не писала этот warning. имхо его можно смело игнорировать.

md5xxx1
()
Ответ на: комментарий от question4

Так для чего?

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

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от md5xxx1

> видимо автор писал просто для всех полей этот аттрибут, и старая версия не писала этот warning. имхо его можно смело игнорировать.

Именно.

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

question4 ★★★★★
() автор топика
Ответ на: комментарий от Boy_from_Jungle

> Тип char не упаковывается

А не наоборот? Он не выравнивается на границы слов, двойных слов и прочего, поэтому всегда получается упакованным.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

А не наоборот?

Да я чуть не так выразился.

Он не выравнивается на границы слов, двойных слов и прочего, поэтому всегда получается упакованным.


Данные в структурах, т.е. размер структуры по умолчанию выравниваются на границу 4байт, но можно установить любое.

Boy_from_Jungle ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.