Перейти к содержанию
    

Как стандартно в Си узнать размер char-а

А напишу-ка я здесь. Прикинусь начинающим.

 

Столкнулся работая с TMS320 с тем, что у него тип char имеет 2 байта. И (кто бы мог подумать) sizeof() выдаёт размеры переменных тоже в 16 битных словах.

Вопрос: как стандартными методами преобразовать этот размер в байтовый размер, то бишь метод должен одинаково работать на всех платформах, и там где sizeof() байтовый.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы сделал так:

 

#ifdef TMS320

#define SIZE_OF_CHAR 2

#else

#define SIZE_OF_CHAR 1

#endif

 

int true_size = SIZE_OF_CHAR * sizeof(char);

 

хотя смотрится это не вот уж...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос: как стандартными методами преобразовать этот размер в байтовый размер, то бишь метод должен одинаково работать на всех платформах, и там где sizeof() байтовый.

 

#include <limits.h>

#define CHAR_BYTES  (CHAR_BIT / 8)

 

Тьху, позор, срочно исправил на более приличный вариант

 

Ну если запараноиться на всякие 9-ти битовые char, то, конечно, посложнее надефайнить придётся, а так - размер в битах (и куча другого полезного) лежит в этом самом limits.h

 

int true_size = SIZE_OF_CHAR * sizeof(char);

 

хотя смотрится это не вот уж...

 

#define BYTESOF(a)  (CHAR_BYTES * sizeof(a))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define BYTESOF(a)  (CHAR_BYTES * sizeof(a))

Справедливости ради надо заметить, что так лажа выйдет на платформе с 16-битным char и "честным" sizeof(), возвращающим размер в байтах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Справедливости ради надо заметить, что так лажа выйдет на платформе с 16-битным char и "честным" sizeof(), возвращающим размер в байтах.

Мне тут SM подсказывает, что sizeof() по стандарту должен выдавать размер как раз в char-ах. Вопрос: так ли это на самом деле?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне тут SM подсказывает, что sizeof() по стандарту должен выдавать размер как раз в char-ах. Вопрос: так ли это на самом деле?

По стандарту C99 - в байтах:

The sizeof operator yields the size (in bytes) of its operand, which may be an

expression or the parenthesized name of a type.

и еще вот это интересно:

When applied to an operand that has type char, unsigned char, or signed char,

(or a qualified version thereof) the result is 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне тут SM подсказывает, что sizeof() по стандарту должен выдавать размер как раз в char-ах. Вопрос: так ли это на самом деле?

Насколько помню, sizeof возвращает размер в минимально адресуемых единицах на данной платформе. И "байтом" обычно эту минимально адресуемую ячейку памяти и называют, другими словами, на этом TMS'е байт как раз 16 бит. Поэтому sizeof выдает правильный результат. А char может иметь любой размер при условии, что он больше 8 бит. Т.е. может иметь хоть 16, хоть 24, хоть 32. При том, что размер байта на этой же платформе может быть и 8 бит. В общем, это отдано на откуп реализации. Но чаще всего char делают размером с байт (по здравому смыслу), т.к. платформы с минимально адресуемой ячейкой менее 8 бит являются экзотикой (равно как и спец фичи типа битовых процессоров MCS-51).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

другими словами, на этом TMS'е байт как раз 16 бит.

На этом TMS-е есть адресации "low_byte(addr)" и "high_byte(addr)" для команд load/store. Так что байт там как у всех. Как есть и битовые операции типа MCS-51. А вот лень у разработчиков компилятора - явно присутствует в изобилии, для char-а могли бы эти адресации использовать, хотя они и выходят за рамки концепции всей системы команд, являясь ее как бы дополнением.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А char может иметь любой размер при условии, что он больше 8 бит. Т.е. может иметь хоть 16, хоть 24, хоть 32. При том, что размер байта на этой же платформе может быть и 8 бит.

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

 

Получается, что sizeof возвращает размер в байтах, который равен размеру в char'ах. А байт и char могут иметь любой размер.

Так что SM прав, посыпаю голову пеплом :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Здесь ещё один прикол есть. В Си не существует типа данных, меньшего char! Даже массив "байт" нельзя создать в системе с 16-бит char. Поэтому есть в системе "байт" или нет его - знает только программист. У меня затык возник когда BIOS процедура, работающая с USB требует передать ей размер именно в байтах (по USB-стандарту), а sizeof() объектов, которые я хочу передать, мне возвращаются в У.Е. И соответствие между USB-bytes и У.Е. мне необходимо вычислить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, тогда вполне подходит способ, предложенный Real'ом: в limits.h для C5500 честно написано, что char имеет размер 16 бит.

Или объекты еще и упакованы по два восьмибитных байта в char?

 

P.S. На 55-м я честно забил на размер char'а, использовав для записи USB дескрипторов только половину, благо их немного. А вот с SD/MMC пришлось извращаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И соответствие между USB-bytes и У.Е. мне необходимо вычислить.

На сколько я помню, в USB далеко не все дескрипторы имеют четную длину. Так что вроде как не судьба автоматом-то считать.

 

По стандарту C99 - в байтах:

 

И по тому же стандарту - байт:

 

1 byte

addressable unit of data storage large enough to hold any member of the basic character

set of the execution environment

2 NOTE 1 It is possible to express the address of each individual byte of an object uniquely.

 

так что все в норме, никто не говорил, что он 8 бит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так что все в норме, никто не говорил, что он 8 бит.

:)

Компиляторописатели... Получается, что "программный" байт и "железный" байт не одно и то же. А если программист читает User Manual, то он реально запутается, т.к. в мануале байт - это честные 8 бит.

 

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

А вот это я вообще не понял. Чего немного?

Изменено пользователем GetSmart

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так что все в норме, никто не говорил, что он 8 бит.

Да. "Вариантов нормы" только много получается :)

 

А вот это я вообще не понял. Чего немного?

Дескрипторов немного, поэтому не жалко использовать половинку от char'а на каждый байт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дескрипторов немного, поэтому не жалко использовать половинку от char'а на каждый байт.

До сих пор не понял.

USB_postTransaction(&EP2_OUT, size, buf, USB_IOFLAG_NOSHORT);

тут size передаётся в "железных" USB-байтах, а buf - указатель на буфер, из которого будет извлечено 100% бит, то есть если это char[10], то оттуда передастся 20 "железных" USB-байт.

Изменено пользователем GetSmart

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...