9.3 Кодирование типов
Это раздел для опытных пользователей. Компилятор и среда выполнения широко используют кодирование типов, но для работы с Objective-C обычно не требуется знать о нём.
Компилятор Objective-C генерирует кодирование типов для всех типов. Во время выполнения это кодирование используется для получения информации о селекторах, методах, объектах и классах.
Типы кодируются следующим образом:
_Bool |
B |
char |
c |
unsigned char |
C |
short |
s |
unsigned short |
S |
int |
i |
unsigned int |
I |
long |
l |
unsigned long |
L |
long long |
q |
unsigned long long |
Q |
float |
f |
double |
d |
long double |
D |
void |
v |
id |
@ |
Class |
# |
SEL |
: |
char* |
* |
enum |
enum кодируется точно так же, как целочисленный тип, который компилятор использует для него; этот тип зависит от значений перечисления. Часто пользователи компилятора unsigned int, которое затем кодируется как I. |
| неизвестный тип | ? |
| Составные типы |
j, за которым следует внутренний тип. Например, _Complex double кодируется как "jd". |
| битовые поля |
b, за которым следуют начальная позиция битового поля, его тип и размер (кодирование битовых полей было изменено по сравнению с кодированием компилятора NeXT; см. ниже) |
Кодирование битовых полей было изменено, чтобы функции среды выполнения, вычисляющие размеры и выравнивание типов, содержащих битовые поля, могли правильно их обрабатывать. Предыдущее кодирование содержало только размер битового поля. Используя только эту информацию, невозможно надёжно вычислить размер, занимаемый битовым полем. Это особенно важно при использовании сборщика мусора Boehm, поскольку объекты выделяются с помощью механизма типизированной памяти, доступного в этом сборщике. Для выделения типизированной памяти требуется информация о том, где внутри объекта расположены указатели.
Позиция битового поля — это позиция в битах ближайшего к началу структуры бита.
Неатомарные типы кодируются следующим образом:
| указатели | «^», за которым следует тип, на который указывает указатель. |
| массивы | «[», за которым следуют количество элементов массива, тип элементов и «]» |
| структуры | «{», за которым следуют имя структуры (или «?», если структура не имеет имени), знак «=», типы полей и «}» |
| объединения | «(», за которым следуют имя структуры (или «?», если объединение не имеет имени), знак «=», типы полей и «)» |
| векторы | «![», за которым следуют vector_size (количество байтов, составляющих вектор), запятая, выравнивание вектора в байтах, тип элементов и «]» |
Ниже приведены некоторые типы и их кодирование, сгенерированное компилятором для машины i386:
| Тип Objective-C | Кодирование компилятора |
|---|---|
int a[10]; |
[10i] |
struct {
int i;
float f[3];
int a:3;
int b:2;
char c;
}
|
{?=i[3f]b128i3b131i2c} |
int a __attribute__ ((vector_size (16))); |
![16,16i] (выравнивание зависит от машины) |
Помимо типов компилятор также кодирует спецификаторы типов. В таблице ниже описано кодирование используемых в настоящее время спецификаторов типов Objective-C:
| Спецификатор | Кодирование |
|---|---|
const |
r |
in |
n |
inout |
N |
out |
o |
bycopy |
O |
byref |
R |
oneway |
V |
Спецификаторы типов кодируются непосредственно перед типом. Однако, в отличие от типов, спецификаторы типов кодируются только в том случае, если они встречаются в типах аргументов метода.
Обратите внимание на взаимодействие const с указателями:
| Тип Objective-C | Кодирование компилятора |
|---|---|
const int |
ri |
const int* |
^ri |
int *const |
r^i |
const int* — это указатель на const int, поэтому он кодируется как ^ri. Напротив, int* const — это указатель const на int, поэтому он кодируется как r^i.
Наконец, при кодировании const char * и char * const возникает сложность. Поскольку char * кодируется как *, а не как ^c, невозможно выразить, относится ли r к указателю или к объекту, на который он указывает.
Поэтому принято считать, что r* означает const
char * (поскольку обычно подразумевается именно это), а закодировать char *const невозможно. char *const просто кодировалось бы как *, и const терялся бы.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Type-encoding.html