Разыменование типа указателя в sizeof()
У меня есть следующая структура:
typedef struct _foo_t {
int bar;
float buzz;
char quux[40];
} *const foo_t;
Есть ли способ получить размер структуры, как это делается с помощью sizeof(struct _foo_t)
, но используя только имя foo_t
? я пытался sizeof(*foo_t)
, но это не компилируется.
4 ответа
Я не верю, что вы можете сделать это напрямую. Вам нужно определить промежуточный typedef, если вы хотите сделать это:
typedef struct _foo_t {
int bar;
float buzz;
char quux[40];
} foo_t;
typedef foo_t *const foo_tp;
// sizeof(foo_t) should work
Разыменование типа на самом деле не имеет смысла в C. Вы можете разыменовать переменную, но не тип. В C++ вы можете выполнять такие операции с типами, используя шаблоны, но это не совсем применимо, поскольку вы указываете тег C.
Вы также можете объявить фиктивную переменную соответствующего типа для вызова sizeof
по выражению:
foo_tp f;
// sizeof(*f) should work
Вы можете сделать это, используя составной литерал, подобный этому:
sizeof(*(foo_t){NULL})
Вы не можете использовать имя типа в качестве операнда (не только для sizeof), поскольку выражение требует наличия типа (в C типы не являются гражданами первого класса, как в полных OO-языках, таких как Python). Однако при использовании версии в скобках вы можете использовать только имя типа - черновик C11 6.5.3.4#1/2. Понятное ограничение.
Обратите внимание, что выражение в скобках после sizeof
Ключевое слово будет иметь различную грамматическую семантику: круглые скобки являются частью выражения, в то время как для имени типа они являются частью sizeof
оператор (который будет работать как вызов функции). (Я действительно не хочу писать парсер для C сам.)
Я для себя обычно не typedef
указатели. Это скрывает семантику и позволяет забыть об их особых (и опасных) свойствах. Исключением может быть внешний интерфейс, где указатель извне используется скорее как дескриптор, чем указатель. Но это я действительно использую только на внешней мембране.
Хорошо, как я понял из обсуждения, вы пытаетесь работать с непрозрачными указателями. Но это не сработает, если в любом случае определить тип структуры и указатель сразу. Вам нужно будет разделить это:
"hidden_stuff.h":
typedef struct HiddenStruct * const HiddenStructHandle;
"hidden_stuff.c"
#include "hidden_stuff.h"
struct HiddenStruct {
...
};
Наличие структуры в заголовке сломает инкапсуляцию / сокрытие.
foo_t
это typedef
так что это как тип.
*foo_t
не является допустимым выражением, потому что вы не можете разыменовать тип.
Поскольку это недопустимое выражение, вы не можете получить его размер.
Это как написание:
typedef int * pointer_to_int_type;
size_t a = sizeof(*pointer_to_int_type);