LINUX.ORG.RU

Подход к портированию, если sizeof(char)=2

 , ,


0

3

Ищу подход, как с наименьшими усилиями портировать код под архитектуру, где sizeof(char)=sizeof(int_8t)=2. Проблема: обмен данными с хостом, у которого привычный размер char, равный 1.

Обычные объявления

typedef struct foo {
  char f1;
  char f2;
};
можно, на первый взгляд, обойти битовыми полями:
typedef struct foo {
  char f1 : 8;
  char f2 : 8;
};
А как элегантно справиться с
typedef struct foo {
  char f[6];
};
?

★★★★★

Так, у битовых полей, похоже, есть свои проблемы с портабельностью: порядок бит, где старший/младший.

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

я не уверен, что раз у тебя байт 16-битный, то получится адресовать 8-битные смещения в массиве средствами языка.

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

По крайней мере в эмуляторе через битовые поля получилось.

gag ★★★★★
() автор топика

ok, а sizeof(uint16_t) чему равен?

самым простым вариантом будет использовать его и маски со сдвигом.

anonymous
()

Это я наркоман, или в стандарте написано, что sizeof должен возвращать размер в char-ах?

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

sizeof должен возвращать размер в char-ах?

это ты наркоман. sizeof(char) == 2*sizeof(char) будет верно только если sizeof(char)==0.

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

ISO/IEC 9899:TC3 пункт 6.5.3.4.3

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

Что за компилятор дает 2?

anonymous
()

Удваиваю анонима выше, компилятор на sizeof(char) должен давать 1 полюбому, так заложено в стандарте.
Так что тут я даже не знаю, что посоветовать.

Reinar
()

Именно sizeof(char)==2? Беги оттуда - мало того, что архитектура экзотическая, так еще и компилятор кривой.

Если всё-таки sizeof(char) == 1 (это не мешает char быть двухбайтовым), а структур данных, которые нуждаются в преобразовании, много - напиши автоматический конвертер. На pycparser, gcc-xml или еще чем-то.

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

@анонимам, Reinar:

Хорошо, проверю. Но не в этом проблема.

gag ★★★★★
() автор топика
Последнее исправление: gag (всего исправлений: 1)

так тебе портировать нужно или обмениваться? Формат обмена данными, если что, не должен зависеть от платформы/архитектуры. Т.е. писать/читать структурами не нужно.

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

Именно sizeof(char)==2? Беги оттуда - мало того, что архитектура экзотическая, так еще и компилятор кривой.

Надо проверить, чтобы наверняка. Корректней было бы сказать, что память адресуется минимум по 16 бит.

Бежать хотел, но сказали, тогда, ведь, придётся портировать не дополнительный код, а весь рабочий код, что, наверняка, будет ещё дольше. Это, конечно, было бы вкладом в будущее, ведь рано или поздно надо будет двигаться далее TMS320C5xx.

Если всё-таки sizeof(char) == 1 (это не мешает char быть двухбайтовым),

Проверю.

а структур данных, которые нуждаются в преобразовании, много - напиши автоматический конвертер. На pycparser, gcc-xml или еще чем-то.

Но не вижу, как можно было бы обойтись преобразованием только структур.

При передаче структуры

struct foo {
   int8_t x;
   int8_t y;
   int8_t z[2];
};
с хоста придёт 32 бита. При обращении на девайсе к x, он будет содержать, скорее всего, x в старших разрядах и y в младших. Это пофиксили (ещё нужно тестировать, чтобы компилятор не поменял x и y местами):
struct foo {
   int8_t x : 8;
   int8_t y : 8;
   int8_t z[2];
};
Теперь x и y упакованы в один 16-битный «int8_t». Причём, код корректен, видимо, как на привычных платформах, так и на этой. Но что делать с z? И это, только пример. Есть ещё инициализации int8_t-массивов, вызовы memcpy,..

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

так тебе портировать нужно или обмениваться?

2в1: портировать код, который обменивается.

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

Формат обмена данными, если что, не должен зависеть от платформы/архитектуры. Т.е. писать/читать структурами не нужно.

Точно нельзя? А то мужики-то и не знают.

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

Но не вижу, как можно было бы обойтись преобразованием только структур.

Генерируй функции:


struct le32_foo {
   int16_t xy;
   int16_t z;
};

struct tms16_foo {
   int16_t x;
   int16_t y;
   int16_t z[2];
};

void le32_to_tms16_foo(const struct le32_foo *in, struct tms16_foo *out)
{
  out->x = in->x & 0xff;
  out->y = (in->x >> 8) & 0xff;
  out->z[0] = in->z & 0xff;
  out->z[1] = (in->z >> 8) & 0xff;
}

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

Спасибо, интересно! Как автоматически поправить код, который использует структуры, пока ещё не вижу: там приходит буффер («8-битный» массив), и потихоньку он интерпретируются то одной структурой, потом по типу вложенной инфы - внутренности другой структурой.

Надо посмотреть, как gcc-xml & Co. использовать с целью автоматизации генерации по крайней мере таких структур. Хотя, их не так много. Лазить по всему коду и контролировать их использование - вот что может стать хорошим источником ошибок, если это не сделать автоматом.

gag ★★★★★
() автор топика
Последнее исправление: gag (всего исправлений: 1)
Ответ на: комментарий от gag

приходит буффер «8-битный» массив и потихоньку его интерпретируют то одной структурой, потом по типу вложенной инфы - внутренности другой структурой.

Похоже, такую ситуацию красиво не разрулить. Можно наделать структур с битовыми полями, а массивы сделать макросами:

struct tms16_foo {
  int x: 8;
  int y: 8;
  struct { uint16_t nm[1]; } _foo_z;
}

#define foo_z(idx) (idx % 2 == 0 ? _foo_z[(idx)/2] & 0xff : (_foo_z[(idx)/2] >> 8) & 0xff)

Но, конечно, это дорога в АдЪ.

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

Точно нельзя?

точно не нужно

А то мужики-то и не знают.

пичаль.

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

Компилятоор микрософта,дельфи/сибуилдера если поставить поддержку уникода-все чары будут 2 байта.

anonymous
()

sizeof(char)=2

Много вариантов...
1.Структура/макрос с переопределением,хотя с магией ссылок будет капец,да.
2.Сделать как сделали в микрософте-перекомпилять компилятор-берешь исходники gcc и правиш там определение типа чар на два байта(вместе с сотнями строк формул расчета сдвигов)
3.Или вникать в суть программы и переписывать под 1байт чар,или вообще все с нуля переписать,на основе логики.

...

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

Ах да

4.Или сделать как 99% кодеров:
Использовать IFDEF
Его используют везде,абсолютно-в qt для обхода «особенностей» компилятора маков и виндов,где своя математика,в томже файрфоксе накостыляли огого сколько ifdef-ами...вообще ifdef это майнстрим.

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

16-битный char и sizeof(char)==2 это разные вещи. Первое возможно, а второе невозможно!

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

Это я наркоман, или в стандарте написано, что sizeof должен возвращать размер в char-ах?

Все верно, по стандарту sizeof(char) всегда должен быть равен 1. Т.к. sizeof возвращает размер не в байтах, а в char-ах, верно. Так что если char - 16-ти битный - это не должно никого волновать, значит на данной архитектуре и байт - 16-ти битный.

Наркоманы - создатели компилятора под ту платформу.

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

Компилятоор микрософта,дельфи/сибуилдера если поставить поддержку уникода-все чары будут 2 байта.

Не путайте char с TCHAR/wchar_t

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

Но не вижу, как можно было бы обойтись преобразованием только структур.

А тебе зачем ими обходиться? Поддерживаю mashina, не передавай структуры. По хорошему, для каждой структуры тебе нужны функции send_struct_foo и recv_struct_foo или функции, приводящие структуры в портабельный формат в буфере. Написать их всяко быстрее, проще и надёжнее, чем ковыряться с битовыми полями и прочим.

auto12884839
()

sizeof(char) == 1 по определению (см. стандарт). Если какое-то другое значение, то у тебя кривой компилятор.

alexeiz
()
Ответ на: комментарий от tailgunner

char в принципе не бывает двухбайтным. Он всегда однобайтный. Байт - минимальная адресуемая единица памяти. То, что в x86 (и некоторых других архитекторах) он равен одному октету еще не означает, что так везде.

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

char в принципе не бывает двухбайтным. Он всегда однобайтный. Байт - минимальная адресуемая единица памяти

Я знал, что найдется знаток, который скажет «у вас просто 16-битный байт».

tailgunner ★★★★★
()

Эээээ... А разве по стандарту sizeof(char) не всегда равен 1? Он может быть не 8битным, но вроде он всегда должен быть 1.

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

Я знал, что найдется знаток, который скажет «у вас просто 16-битный байт».

Эм, байт может быть 16битным. Но sizeof его всегда 1. Иначе быть не может.

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

Эм, байт может быть 16битным. Но sizeof его всегда 1

А что, в Си есть «sizeof байта»? Любителям терминологической точности следтует либо говорить «sizeof(char) всегда 1», либо «16-битный байт». Либо трусы, либо крестик.

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

В стандарте дано определение, что char это минимально адресуемая память на данной платформе. Что и есть байт по определению.

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

В стандарте дано определение, что char это минимально адресуемая память на данной платформе. Что и есть байт по определению.

Байт - это единица информации, а не единица адресации; в стандарте есть char, а байта нет </thread>

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

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

Historically, the byte was the number of bits used to encode a single character of text in a computer[1][2] and for this reason it is the smallest addressable unit of memory in many computer architectures

Dudraug ★★★★★
()

ты бредишь. sizeof(char) == 1 по определению и стандарту. Отпиши быдлокодерам о их криворукости.

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

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

а при чём тут C?

Historically, the byte was the number of bits used to encode a single character of text in a computer[1][2] and for this reason it is the smallest addressable unit of memory in many computer architectures

читать и обдумывать выделенное слово.

_обычно_ byte === char. Но не всегда.

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

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

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

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

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

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

Так о том и речь же=)

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

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

Это был упрек?

Да. С твоего поста началось скатывание темы в унылый оффтопик.

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

а также @анонимам, Reinar, Reset, qrck, alexeiz, RiseOfDeath, Dudraug, drBatty:

Всё, проверил. Как все и ожидали sizeof(char) == 1. Ещё раз сорри за неудачно выбранную формулировку в заголовке. Кстати, и sizeof(int) == 1.

Вообще, я надеялся отлаживать порт удобненько под gcc/линуксом, используя

//#include <stdint.h>
typedef          short int   int8_t;
typedef unsigned short int  uint8_t;
typedef          short int  int16_t;
typedef unsigned short int uint16_t;
// ...
Но даже это, похоже, так просто не выйдет. Как минимум из-за sizeof(int16_t) == 2. Или можно это дело тоже как-то переопределить?

P.S. Кстати, на C6x, кажись, gcc уже портировали, а на C5x - нет.

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

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

а почему нет? А почему «меньше»? Кстати, современные компы уже давно байты не умеют, читают как минимум по 64 бита, и потом выбирают нужный байт. Т.е. чтение по байтам — эмуляция.

Потому что char по определению минимальная адресуемая память.

не имеет char никакого отношения к памяти и байтам. Это тип данных в C. Размер его в битах/байтах НЕ ОПРЕДЕЛЁН. Он сам по себе единица измерения. Известно, что sizef(char) == 1, и что например sizeof(int) ≥ 1.

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