Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как стандартно в Си узнать размер char-а
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
GetSmart
А напишу-ка я здесь. Прикинусь начинающим.

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

#ifdef TMS320
#define SIZE_OF_CHAR 2
#else
#define SIZE_OF_CHAR 1
#endif

int true_size = SIZE_OF_CHAR * sizeof(char);

хотя смотрится это не вот уж...
ReAl
Цитата(GetSmart @ Aug 20 2009, 20:24) *
Вопрос: как стандартными методами преобразовать этот размер в байтовый размер, то бишь метод должен одинаково работать на всех платформах, и там где sizeof() байтовый.


Код
#include <limits.h>

#define CHAR_BYTES  (CHAR_BIT / 8)


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

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

Цитата(Axel @ Aug 20 2009, 22:40) *
int true_size = SIZE_OF_CHAR * sizeof(char);

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


Код
#define BYTESOF(a)  (CHAR_BYTES * sizeof(a))
aaarrr
Цитата(ReAl @ Aug 21 2009, 00:33) *
Код
#define BYTESOF(a)  (CHAR_BYTES * sizeof(a))

Справедливости ради надо заметить, что так лажа выйдет на платформе с 16-битным char и "честным" sizeof(), возвращающим размер в байтах.
GetSmart
Цитата(aaarrr @ Aug 21 2009, 04:30) *
Справедливости ради надо заметить, что так лажа выйдет на платформе с 16-битным char и "честным" sizeof(), возвращающим размер в байтах.

Мне тут SM подсказывает, что sizeof() по стандарту должен выдавать размер как раз в char-ах. Вопрос: так ли это на самом деле?
aaarrr
Цитата(GetSmart @ Aug 21 2009, 07:59) *
Мне тут 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.
dxp
Цитата(GetSmart @ Aug 21 2009, 10:59) *
Мне тут SM подсказывает, что sizeof() по стандарту должен выдавать размер как раз в char-ах. Вопрос: так ли это на самом деле?

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

На этом TMS-е есть адресации "low_byte(addr)" и "high_byte(addr)" для команд load/store. Так что байт там как у всех. Как есть и битовые операции типа MCS-51. А вот лень у разработчиков компилятора - явно присутствует в изобилии, для char-а могли бы эти адресации использовать, хотя они и выходят за рамки концепции всей системы команд, являясь ее как бы дополнением.
aaarrr
Цитата(dxp @ Aug 21 2009, 08:13) *
А char может иметь любой размер при условии, что он больше 8 бит. Т.е. может иметь хоть 16, хоть 24, хоть 32. При том, что размер байта на этой же платформе может быть и 8 бит.

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

Получается, что sizeof возвращает размер в байтах, который равен размеру в char'ах. А байт и char могут иметь любой размер.
Так что SM прав, посыпаю голову пеплом smile.gif
GetSmart
Цитата(aaarrr @ Aug 21 2009, 10:39) *
Тогда несостыковка получается, т.к. явно указывается, что sizeof(char)=1. То есть если у системы восьмибитный байт, то char тоже обязан быть восьмибитным.

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

P.S. На 55-м я честно забил на размер char'а, использовав для записи USB дескрипторов только половину, благо их немного. А вот с SD/MMC пришлось извращаться.
SM
Цитата(GetSmart @ Aug 21 2009, 08:54) *
И соответствие между USB-bytes и У.Е. мне необходимо вычислить.

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

Цитата(aaarrr @ Aug 21 2009, 08:05) *
По стандарту 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 бит.
GetSmart
Цитата(SM @ Aug 21 2009, 11:09) *
так что все в норме, никто не говорил, что он 8 бит.

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

Цитата(aaarrr @ Aug 21 2009, 11:00) *
... использовав для записи USB дескрипторов только половину, благо их немного.

А вот это я вообще не понял. Чего немного?
aaarrr
Цитата(SM @ Aug 21 2009, 09:09) *
так что все в норме, никто не говорил, что он 8 бит.

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

Цитата(GetSmart @ Aug 21 2009, 09:27) *
А вот это я вообще не понял. Чего немного?

Дескрипторов немного, поэтому не жалко использовать половинку от char'а на каждый байт.
GetSmart
Цитата(aaarrr @ Aug 21 2009, 11:43) *
Дескрипторов немного, поэтому не жалко использовать половинку от char'а на каждый байт.

До сих пор не понял.
Код
USB_postTransaction(&EP2_OUT, size, buf, USB_IOFLAG_NOSHORT);

тут size передаётся в "железных" USB-байтах, а buf - указатель на буфер, из которого будет извлечено 100% бит, то есть если это char[10], то оттуда передастся 20 "железных" USB-байт.
aaarrr
Цитата(GetSmart @ Aug 21 2009, 10:04) *
До сих пор не понял.

Просто BIOS я не использовал.

Цитата(GetSmart @ Aug 21 2009, 10:04) *
тут size передаётся в "железных" USB-байтах, а buf - указатель на буфер, из которого будет извлечено 100% бит, то есть если это char[10], то оттуда передастся 20 "железных" USB-байт.

Тады ой - с нечетным количеством данных получаются грабли sad.gif
ReAl
Цитата(GetSmart @ Aug 21 2009, 09:04) *
тут size передаётся в "железных" USB-байтах
А Вы говорите "октет", как в сетях принято :-)
Именно потому, что байты - они всякие бывают.
aaarrr
Цитата(ReAl @ Aug 21 2009, 14:23) *
А Вы говорите "октет", как в сетях принято :-)

Да-да, тоже почему-то это слово вспомнилось smile.gif Но ведь сила привычки, от байтов отучиться трудно.
GetSmart
Цитата(ReAl @ Aug 21 2009, 16:23) *
А Вы говорите "октет", как в сетях принято :-)
Именно потому, что байты - они всякие бывают.

Цитата(http://en.wikipedia.org/wiki/Byte)
The popularity of IBM's System/360 architecture starting in the 1960s and the explosion of microcomputers based on 8-bit microprocessors in the 1980s has made eight bits by far the most common size for a byte. The term octet is widely used as a more precise synonym where ambiguity is undesirable (for example, in protocol definitions).

Ну да, исхитрились. Хотя в русской литературе везде байтом считается 8 бит без каких-либо оговорок.

Даже в доке от TI
Цитата(spru587e.pdf @ page 28)
Byte = An 8-bit value. A byte is the smallest unit of data transferred in a DMA channel.
dxp
Цитата(SM @ Aug 21 2009, 11:22) *
На этом TMS-е есть адресации "low_byte(addr)" и "high_byte(addr)" для команд load/store. Так что байт там как у всех.

А по скорости/накладным они такие же, как и для словной адресации? Или это некое расширение, реализуемое за счет эмуляции (типа, слово считывается целиком, в АЛУ модифицируется нужный байт и потом складываются в память)?

Цитата(aaarrr @ Aug 21 2009, 11:39) *
Тогда несостыковка получается, т.к. явно указывается, что sizeof(char)=1. То есть если у системы восьмибитный байт, то char тоже обязан быть восьмибитным.

Да, насчет sizeof(char) был неправ (давно было, забывать начал smile.gif ). В плюсах тоже так же: sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1;
SM
Цитата(dxp @ Aug 21 2009, 16:33) *
А по скорости/накладным они такие же, как и для словной адресации? Или это некое расширение, реализуемое за счет эмуляции (типа, слово считывается целиком, в АЛУ модифицируется нужный байт и потом складываются в память)?

Да, по скорости и накладным тоже самое, но только в том случае, если заранее известно, какой байт нужен - low или high. К АЛУ это отношения не имеет, так как при обращениях оно управляет сигналами "byte enable (BE[1:0])" шины, или DQM-ами, если это SDRAM. Но адрес-то при этом все равно словесный, а выбор байта осуществляется при помощи указания конкретной команды ассемблера. Т.е. если организовывать полностью произвольный доступ к любому байту - то нужно иметь словесный адрес, бит выбора байта и условное выполнение той или другой команды. Плюс ко всему, если слово памяти может быть аргументом любой арифметики и можно сказать любой операции вообще, то байт из памяти только или load, или store.
defunct
Цитата(SM @ Aug 21 2009, 15:49) *
Т.е. если организовывать полностью произвольный доступ к любому байту - то нужно иметь словесный адрес, бит выбора байта и условное выполнение той или другой команды. Плюс ко всему, если слово памяти может быть аргументом любой арифметики и можно сказать любой операции вообще, то байт из памяти только или load, или store.

Очередное дерьмецо от TI... Годное только для обработки звука.
Непонятно только зачем там USB.
GetSmart
Цитата(defunct @ Aug 21 2009, 22:46) *
В общем очередное дерьмецо от TI... Годное только для обработки звука.

Щас SM Вас порвёт biggrin.gif

На самом деле, раз адресация в проце на 90% только пословная, то TI сделали правильно. Там только DMA имеет байтовый адрес.

Асмописатели на TMS наверное очень довольны такой архитектурой, в отличие от сишников. SM как раз один из них.
defunct
Цитата(GetSmart @ Aug 21 2009, 19:52) *
Щас SM Вас порвёт biggrin.gif

Ну от этого Вам будет не легче передать фрейм нечетной длины. :P

А TI изделия (без учета приобретений на стороне - BB, Luminary и т.п.) всегда считал и продолжаю считать неадекватными, за редким исключением.
Почти каждый их DSP / MK - это "шедевр" smile.gif полученный в результате больной фантазии индусов.
SM
Цитата(defunct @ Aug 21 2009, 21:01) *
Ну от этого Вам будет не легче передать фрейм нечетной длины. :P

Да легко. DMA-контроллером без участия проца вообще. Откуда угодно, куда угодно, по любым событиям, включая внешние. Это только С-шникам некоторые трудности, да и то, из-за писателей CSL и DSP/BIOS. Без них напрягов нет никаких.
GetSmart
Цитата(defunct @ Aug 21 2009, 23:01) *
Ну от этого Вам будет не легче передать фрейм нечетной длины. :P

Проблема не в невозможности, а в неудобстве/некрасивости сишной реализации.
Andron_
Цитата(dxp @ Aug 21 2009, 11:13) *
Насколько помню, sizeof возвращает размер в минимально адресуемых единицах на данной платформе. И "байтом" обычно эту минимально адресуемую ячейку памяти и называют, другими словами, на этом TMS'е байт как раз 16 бит. Поэтому sizeof выдает правильный результат.

в каком-то из TI'ных мануалов есть фраза что-то вроде "вообще-то байт конечно 8 бит, но если очень хочется, как у нас, то байт будет 16 бит. Именно в этих 16-ти битных байтах и выдает результат sizeof"... я еще над ней посмеялся))))
aaarrr
Ну а в C99 написано:
Цитата
3.6
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.
3 NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementationdefined.
The least significant bit is called the low-order bit; the most significant bit is called the high-order
bit.

Так что техасцы в своем праве.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.