typedef struct __packed st1
{
int a,
char b;
int c;
}_st1;
Требуется написать это же (!!!) на МС-овском си.
Проблема в том, что
1) #pragma pack(1) — требует возвращения упаковки поумолчанию. Типа pack(push,1) ла-ла-ла pack(pop) в отличии от __attribute__ https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
2) наличие '#' нельзя использовать в макросах, НО есть выход __pragma(pack(1))
3) проблема в том, что вот такой код поедается
typedef struct
#pragma pack(1)
st1
{
int a,
char b;
int c;
}_st1;
а вот такой нет
#define __packed __pragma(pack(1))
typedef struct __packed st1
{
int a,
char b;
int c;
}_st1;
То есть задача то простая — сделать так чтобы струкутры с атрибутами GCC были упакованы но можно только переопределелять слово __packed, которое стоит в коде местами после struct.
Здравствуйте, Andrew.W Worobow, Вы писали:
AWW>То есть задача то простая — сделать так чтобы струкутры с атрибутами GCC были упакованы но можно только переопределелять слово __packed, которое стоит в коде местами после struct.
Советую прямо сейчас перестать решать эту задачу. И перенести макрос __packed в другое место, либо использовать #pragma pack везде, либо завернуть декларацию или её часть в другой макрос (как уже подсказали
), либо воспользоваться ещё одним из полдюжины способов выразить семантику packed одинаковым способом в обоих компиляторах.
В любом случае только одной заменой определения макроса __packed проблема не решится, так что нет смысла откладывать.
Да и вообще, неужели в коде так часто используется атрибут packed, что его замена вызывает проблемы? Раз так, то может вообще стоит либо использовать кодогенерацию, либо изменить настройки компиляции, или даже поискать другие нестандартные решения вроде написания собственного препроцессора :)
Здравствуйте, watchmaker, Вы писали:
W>В любом случае только одной заменой определения макроса __packed проблема не решится, так что нет смысла откладывать.
W>Да и вообще, неужели в коде так часто используется атрибут packed, что его замена вызывает проблемы? Раз так, то может вообще стоит либо использовать кодогенерацию, либо изменить настройки компиляции, или даже поискать другие нестандартные решения вроде написания собственного препроцессора
Написать свой препороцессор это варинат, я их уже штук пять в своей жизни написал.
Почему "замена" не подходил?
Тут такое дело — это код типа кросплатформенный и трогать его нельзя.
==
Но походу придется редактировать.
Здравствуйте, Andrew.W Worobow, Вы писали:
AWW>Ну я же написал — что вроде есть __pragma, да вот она между struct и именем не работает.
А что вы можете менять ?
Вы хотите взять код совсем без изменений и скомпилировать его на другом компиляторе ?
Это редко работает в случае специфичных возможностей компилятора.
Как вариант можно скомпилировать проект с опцией /Zp:1 если все структуры упакованы одинаково.
AWW>Тут такое дело — это код типа кросплатформенный и трогать его нельзя.
Это всё же два разных утверждения. Если трогать нельзя, то это одно. А вот атрибут packed кросплатформенно навесить — дело совсем другое.
Способов много, например:
#pragma pack(1)
struct __packed S { ... };
#pragma pack()
Чем такой код не кросплатформенный? Раскрываешь макрос __packed в пустоту под msvc, и в нужный атрибут в gcc/clang. Вполне себе вариант. Да или вообще от __packed можно отказаться — gcc с #pragma pack умеет работать.
AWW>Почему "замена" не подходил?
msvc не допускает в этом контексте ничего подходящего.
Здравствуйте, _NN_, Вы писали:
AWW>>Ну я же написал — что вроде есть __pragma, да вот она между struct и именем не работает.
_NN>А что вы можете менять ?
хм...
_NN>Вы хотите взять код совсем без изменений и скомпилировать его на другом компиляторе ? _NN>Это редко работает в случае специфичных возможностей компилятора.
Для этого и вставили __packed, в обявления и убрали всю "специфику" да вот видать, не добились переносимости.
_NN>Как вариант можно скомпилировать проект с опцией /Zp:1 если все структуры упакованы одинаково.
Ну это что-то такое что и "завернуть" всю декларацию в дефайн.
Здравствуйте, Andrew.W Worobow, Вы писали:
_NN>>Вы хотите взять код совсем без изменений и скомпилировать его на другом компиляторе ? _NN>>Это редко работает в случае специфичных возможностей компилятора.
AWW>Для этого и вставили __packed, в обявления и убрали всю "специфику" да вот видать, не добились переносимости.
Ясно, надо было сразу проверять на MSVC
В принципе сам #pragma pack работает на большинстве компиляторов.
Здравствуйте, watchmaker, Вы писали:
AWW>>Тут такое дело — это код типа кросплатформенный и трогать его нельзя. W>Это всё же два разных утверждения. Если трогать нельзя, то это одно. А вот атрибут packed кросплатформенно навесить — дело совсем другое.
Это код кросплатформенный. Он уже есть и его трогать нельзя. Он такой какое есть.
И кстати у меня есть почти уверенность что "как-то" это сделать можно. И именно через переопределение __packed
W>Способов много, например:
Чем такой код не кросплатформенный? Раскрываешь макрос __packed в пустоту под msvc, и в нужный атрибут в gcc/clang. Вполне себе вариант. Да или вообще от __packed можно отказаться — gcc с #pragma pack умеет работать.
Проблема не в том, "как бы так написать", написать я могу предложить варинтов 100, а проблема не трогая уже готовый код получить перенос того что есть для МС-а.
AWW>>Почему "замена" не подходил? W>msvc не допускает в этом контексте ничего подходящего.
Это более того даже не С++, а СИ.
На МС-е пушут пуш пак поп. А вот аналог атрибутов кроме как не доделанного __deckspec нет. Это да.
Здравствуйте, _NN_, Вы писали:
_NN>Ясно, надо было сразу проверять на MSVC
Ну просто над этим кодом работало и работает сотни человек и как минимум с 2003 года. То есть когда начинали никто про МС даже не думал. Думали про все что угодно но только не про МС. ))
_NN>Можно сделать пару макросов для переносимости
_NN>
Здравствуйте, Andrew.W Worobow, Вы писали:
AWW>И кстати у меня есть почти уверенность что "как-то" это сделать можно. И именно через переопределение __packed
А думаешь, я просто так посоветовал перестать решать эту задачу?
Может ощущения существования "какого-то решения" и есть. Но самого решение — нет :)
Здравствуйте, watchmaker, Вы писали:
W>Может ощущения существования "какого-то решения" и есть. Но самого решение — нет
А ты думашь ошушения так просто возникли? Нет. Сделали "давно", код потеряли, да вот теперь еще и забыли как делали.
Такое ощущение существования подойдет?
MS>typedef struct __packed st1
MS>{
MS> int a,
MS> char b;
MS> char c[4];
MS>}_st1;
MS>
MS>а дальше либо кастишь к int (если x86) либо собираешь int из c[4] на остальных нормальных платформах
Вот только b и c будут иметь выравнивание в 4 байта, а с pragma pack у них будет выравнивание в 1 байт. Размер структуры соответственно тоже будет другим.
W>>Может ощущения существования "какого-то решения" и есть. Но самого решение — нет
AWW>А ты думашь ошушения так просто возникли? Нет. Сделали "давно", код потеряли, да вот теперь еще и забыли как делали.
надо лечиться и использовать vcs. AWW>Такое ощущение существования подойдет?
blame поможет.
Здравствуйте, Andrew.W Worobow, Вы писали:
AWW>Для этого и вставили __packed, в обявления и убрали всю "специфику" да вот видать, не добились переносимости.
охренеть решение — вставить какую-то хрень и надеятся на авось, что она заработает
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
У>>>Не совсем то, но может помочь. _NN>>Точнее совсем не то V>почему не то? чем не подходит?
Здравствуйте, _NN_, Вы писали:
У>>>>Не совсем то, но может помочь. _NN>>>Точнее совсем не то V>>почему не то? чем не подходит?
_NN>Ну pack и align это все же разные вещи.
Да, это я ошибся — я просто глянул примеры (а там писалось, что это результат /Zp и __declspec(align(#))), и решил, что __declspec(align(#)) тоже влияет на упаковку. А на самом деле упаковкой занимается /Zp, он же pragma pack
Здравствуйте, dr. Acula, Вы писали: AWW>>А ты думашь ошушения так просто возникли? Нет. Сделали "давно", код потеряли, да вот теперь еще и забыли как делали. DA>надо лечиться и использовать vcs. AWW>>Такое ощущение существования подойдет? DA>blame поможет.